2 * See the dyninst/COPYRIGHT file for copyright information.
4 * We provide the Paradyn Tools (below described as "Paradyn")
5 * on an AS IS basis, and do not warrant its validity or performance.
6 * We reserve the right to update, modify, or discontinue this
7 * software at any time. We shall have no obligation to supply such
8 * updates or modifications or any other form of support to you.
10 * By your use of Paradyn, you understand and agree that we (or any
11 * other person or entity with proprietary rights in Paradyn) are
12 * under no obligation to provide either maintenance services,
13 * update services, notices of latent defects, or correction of
14 * defects for Paradyn.
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
31 #ifndef INST_AARCH64_H
32 #define INST_AARCH64_H
38 #define LIVE_UNCLOBBERED_REG 2
39 #define LIVE_CLOBBERED_REG 3
46 #define REG_TOC 2 /* TOC anchor */
47 // REG_GUARD_OFFSET and REG_GUARD_VALUE could overlap.
48 #define REG_GUARD_ADDR 5 /* Arbitrary */
49 #define REG_GUARD_VALUE 6
50 #define REG_GUARD_OFFSET 6
52 #define REG_COST_ADDR 5
53 #define REG_COST_VALUE 6
55 #define REG_SCRATCH 10
57 #define REG_MT_POS 12 /* Register to reserve for MT implementation */
58 #define NUM_INSN_MT_PREAMBLE 26 /* number of instructions required for */
59 /* the MT preamble. */
61 // The stack grows down from high addresses toward low addresses.
62 // There is a maximum number of bytes on the stack below the current
63 // value of the stack frame pointer that a function can use without
64 // first establishing a new stack frame. When our instrumentation
65 // needs to use the stack, we make sure not to write into this
66 // potentially used area. AIX documentation stated 220 bytes as
67 // the maximum size of this area. 64-bit PowerPC ELF ABI Supplement,
68 // Version 1.9, 2004-10-23, used by Linux, stated 288 bytes for this
69 // area. We skip the larger number of bytes (288) to be safe on both
70 // AIX and Linux, 32-bit and 64-bit.
73 // Both 32-bit and 64-bit PowerPC ELF ABI documents for Linux state
74 // that the stack frame pointer value must always be 16-byte (quadword)
75 // aligned. Use the following macro on all quantities used to
76 // increment or decrement the stack frame pointer.
77 #define ALIGN_QUADWORD(x) ( ((x) + 0xf) & ~0xf ) //x is positive or unsigned
79 #define GPRSAVE_32 (32*4)
80 #define GPRSAVE_64 (32*8)
81 #define FPRSAVE (14*8)
82 #define SPRSAVE_32 (6*4+8)
83 #define SPRSAVE_64 (6*8+8)
84 #define FUNCSAVE_32 (32*4)
85 #define FUNCSAVE_64 (32*8)
86 #define FUNCARGS_32 (16*4)
87 #define FUNCARGS_64 (16*8)
88 #define LINKAREA_32 (6*4)
89 #define LINKAREA_64 (6*8)
92 #define PARAM_OFFSET(mutatee_address_width) \
94 ((mutatee_address_width) == sizeof(uint64_t)) \
95 ? ( /* 64-bit ELF PowerPC Linux */ \
96 sizeof(uint64_t) + /* TOC save */ \
97 sizeof(uint64_t) + /* link editor doubleword */ \
98 sizeof(uint64_t) + /* compiler doubleword */ \
99 sizeof(uint64_t) + /* LR save */ \
100 sizeof(uint64_t) + /* CR save */ \
101 sizeof(uint64_t) /* Stack frame back chain */ \
103 : ( /* 32-bit ELF PowerPC Linux */ \
104 sizeof(uint32_t) + /* LR save */ \
105 sizeof(uint32_t) /* Stack frame back chain */ \
108 #elif defined(os_vxworks)
109 #define PARAM_OFFSET(bah) (0)
111 #error "Unknown operating system in inst-power.h"
115 // Okay, now that we have those defined, let's define the offsets upwards
116 #define TRAMP_FRAME_SIZE_32 ALIGN_QUADWORD(STACKSKIP + GPRSAVE_32 + FPRSAVE \
118 + FUNCSAVE_32 + FUNCARGS_32 + LINKAREA_32)
119 #define TRAMP_FRAME_SIZE_64 ALIGN_QUADWORD(STACKSKIP + GPRSAVE_64 + FPRSAVE \
121 + FUNCSAVE_64 + FUNCARGS_64 + LINKAREA_64)
122 #define PDYN_RESERVED_32 (LINKAREA_32 + FUNCARGS_32 + FUNCSAVE_32)
123 #define PDYN_RESERVED_64 (LINKAREA_64 + FUNCARGS_64 + FUNCSAVE_64)
125 #define TRAMP_SPR_OFFSET_32 (PDYN_RESERVED_32) /* 4 for LR */
127 #define STK_CR_32 (STK_LR + 4)
128 #define STK_CTR_32 (STK_CR_32 + 4)
129 #define STK_XER_32 (STK_CTR_32 + 4)
130 #define STK_FP_CR_32 (STK_XER_32 + 4)
131 #define STK_SPR0_32 (STK_FP_CR_32+ 8)
133 #define TRAMP_SPR_OFFSET_64 (PDYN_RESERVED_64)
134 #define STK_CR_64 (STK_LR + 8)
135 #define STK_CTR_64 (STK_CR_64 + 8)
136 #define STK_XER_64 (STK_CTR_64 + 8)
137 #define STK_FP_CR_64 (STK_XER_64 + 8)
138 #define STK_SPR0_64 (STK_FP_CR_64+ 8)
140 #define TRAMP_SPR_OFFSET(x) (((x) == 8) ? TRAMP_SPR_OFFSET_64 : TRAMP_SPR_OFFSET_32)
142 #define TRAMP_FPR_OFFSET_32 (TRAMP_SPR_OFFSET_32 + SPRSAVE_32)
143 #define TRAMP_FPR_OFFSET_64 (TRAMP_SPR_OFFSET_64 + SPRSAVE_64)
144 #define TRAMP_FPR_OFFSET(x) (((x) == 8) ? TRAMP_FPR_OFFSET_64 : TRAMP_FPR_OFFSET_32)
146 #define TRAMP_GPR_OFFSET_32 (TRAMP_FPR_OFFSET_32 + FPRSAVE)
147 #define TRAMP_GPR_OFFSET_64 (TRAMP_FPR_OFFSET_64 + FPRSAVE)
148 #define TRAMP_GPR_OFFSET(x) (((x) == 8) ? TRAMP_GPR_OFFSET_64 : TRAMP_GPR_OFFSET_32)
150 #define FUNC_CALL_SAVE_32 (LINKAREA_32 + FUNCARGS_32)
151 #define FUNC_CALL_SAVE_64 (LINKAREA_64 + FUNCARGS_64)
152 #define FUNC_CALL_SAVE(x) (((x) == 8) ? FUNC_CALL_SAVE_64 : FUNC_CALL_SAVE_32)
154 ///////////////////////////// Multi-instruction sequences
157 void saveSPR(codeGen &gen,
161 void restoreSPR(codeGen &gen,
165 void saveLR(codeGen &gen,
168 void restoreLR(codeGen &gen,
171 void setBRL(codeGen &gen,
174 unsigned ti); // We're lazy and hand in the next insn
175 void saveCR(codeGen &gen,
178 void restoreCR(codeGen &gen,
181 void saveFPSCR(codeGen &gen,
184 void restoreFPSCR(codeGen &gen,
187 void saveRegister(codeGen &gen,
190 // We may want to restore a _logical_ register N
191 // (that is, the save slot for N) into a different reg.
192 // This avoids using a temporary
193 void restoreRegister(codeGen &gen,
197 // Much more common case
198 void restoreRegister(codeGen &gen,
201 void saveFPRegister(codeGen &gen,
205 void restoreFPRegister(codeGen &gen,
209 void restoreFPRegister(codeGen &gen,
212 void pushStack(codeGen &gen);
213 void popStack(codeGen &gen);
214 unsigned saveGPRegisters(codeGen &gen,
215 registerSpace *theRegSpace,
216 int save_off, int numReqGPRs=-1);
217 unsigned restoreGPRegisters(codeGen &gen,
218 registerSpace *theRegSpace,
220 unsigned saveFPRegisters(codeGen &gen,
221 registerSpace *theRegSpace,
223 unsigned restoreFPRegisters(codeGen &gen,
224 registerSpace *theRegSpace,
226 unsigned saveSPRegisters(codeGen &gen, registerSpace *,
227 int save_off, int force_save);
228 unsigned restoreSPRegisters(codeGen &gen, registerSpace *,
229 int save_off, int force_save);