Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | /* * Copyright (c) 2024 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #ifndef mach_o_Instructions_h #define mach_o_Instructions_h #include <stdint.h> #include "MachODefines.h" namespace mach_o { /*! * @class Instructions * * @abstract * Helpers to parse instructions */ struct VIS_HIDDEN Instructions { /*! * @class arm64 * * @abstract * Helpers to parse arm64 instructions */ class VIS_HIDDEN arm64 { public: struct Imm12Info { enum class Kind { add, load, store }; uint8_t dstReg; uint8_t srcReg; uint8_t scale; // 1,2,4,8, or 16 uint32_t offset; // imm12 after scaling Kind kind; bool signEx; // if load is sign extended bool isFloat; // if destReg is FP/SIMD }; struct AdrpInfo { uint8_t dstReg; int32_t pageOffset; }; static bool isImm12(uint32_t instruction, Imm12Info& info); static bool isADRP(uint32_t instruction, AdrpInfo& info); static bool isB26(uint32_t instruction, int32_t& delta); static bool setADRPTarget(uint32_t& instruction, uint64_t instructionAddr, uint64_t targetAddr); static bool setImm12(uint32_t& instruction, uint16_t imm12); static bool setB26Target(uint32_t& instruction, uint64_t instructionAddr, uint64_t targetAddr); static bool changeLDRtoADD(uint32_t& instruction, uint16_t imm12); }; /*! * @class arm * * @abstract * Helpers to parse arm/thumb instructions */ class VIS_HIDDEN arm { public: enum BranchKind { b, bl, blx }; // arm instructions // isCond => true, when this is a 32-bit ARM conditionally executed branch // (the condition's code is encoded in the 4 top bits) static bool isBranch24(uint32_t instruction, uint32_t instructionAddr, BranchKind& kind, uint32_t& targetAddr, bool& isCond); // \a instruction must be initialized to the input instruction value, // so that the conditional code can be preserved static bool makeBranch24(BranchKind kind, uint64_t instructionAddr, uint64_t targetAddr, bool targetIsThumb, uint32_t& instruction); static bool isMovt(uint32_t instruction, uint16_t& value); static bool setMovt(uint32_t& instruction, uint16_t value); static bool isMovw(uint32_t instruction, uint16_t& value); static bool setMovw(uint32_t& instruction, uint16_t value); // thumb instructions static bool isThumbBranch22(uint32_t instruction, uint32_t instructionAddr, BranchKind& kind, uint32_t& targetAddr); static bool makeThumbBranch22(BranchKind kind, uint64_t instructionAddr, uint64_t targetAddr, bool targetIsThumb, uint32_t& instruction); static bool isThumbMovt(uint32_t instruction, uint16_t& value); static bool setThumbMovt(uint32_t& instruction, uint16_t value); static bool isThumbMovw(uint32_t instruction, uint16_t& value); static bool setThumbMovw(uint32_t& instruction, uint16_t value); }; #if INTERNAL_BUILD /*! * @class riscv * * @abstract * Helpers to parse riscv instructions */ class VIS_HIDDEN riscv { public: enum Lo12Kind { addi, lw, other_Itype, other_Stype }; static bool isJ20(uint32_t instruction, uint64_t instructionAddr, uint64_t& targetAddr); static bool setJ20Target(uint64_t instructionAddr, uint64_t targetAddr, uint32_t& instruction); static bool isLUI(uint32_t instruction); static bool isLo12(uint32_t instruction, Lo12Kind& kind, int16_t& value, uint8_t& srcRegister); static bool setLo12(uint16_t lo12, uint32_t& instruction); static bool forceADDI(uint16_t lo12, uint32_t& instruction); static bool isAUIPC(uint32_t auipcInstruction, uint8_t& dstRegister); static bool setAUIPCTarget(uint32_t& instruction, uint64_t instructionAddr, uint64_t targetAddr); static bool setLUITarget(uint32_t& instruction, uint64_t targetAddr); }; #endif }; } // namespace mach_o #endif /* mach_o_Instructions_h */ |