Skip to content

Commit 49b4802

Browse files
authored
Update stub.h
1 parent 280263f commit 49b4802

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

src/stub.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,54 @@
204204
*(unsigned long long*)(fn + 12) = (unsigned long long)fn_stub;\
205205
CACHEFLUSH((char *)fn, CODESIZE);
206206
#define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub)
207+
#elif defined(__powerpc64__) && __LITTLE_ENDIAN__
208+
// For ppc64le (ELFv2 ABI with function descriptors)
209+
#define CODESIZE 36U
210+
#define CODESIZE_MIN 36U
211+
#define CODESIZE_MAX CODESIZE
212+
/*
213+
* This hook loads the address of the stub function's descriptor,
214+
* then loads the code entry point and TOC address from the descriptor,
215+
* and finally performs an indirect branch.
216+
*
217+
* Assembly equivalence:
218+
* // Step 1: Load the 64-bit address of the function descriptor for `fn_stub` into r11
219+
* lis r11, fn_stub_desc@highest
220+
* ori r11, r11, fn_stub_desc@higher
221+
* rldicr r11, r11, 32, 31
222+
* ori r11, r11, fn_stub_desc@h
223+
* ori r11, r11, fn_stub_desc@l
224+
*
225+
* // Step 2: Load values from the function descriptor
226+
* ld r12, 0(r11) // Load code address into r12 from descriptor
227+
* ld r2, 8(r11) // Load TOC address into r2 from descriptor
228+
*
229+
* // Step 3: Branch
230+
* mtctr r12 // Move code address to Count Register
231+
* bctr // Branch to the address in CTR
232+
*/
233+
#define REPLACE_FAR(t, fn, fn_stub)\
234+
do {\
235+
uint64_t desc_addr = (uint64_t)fn_stub;\
236+
uint32_t* p = (uint32_t*)fn;\
237+
/* Load 64-bit descriptor address into r11 */ \
238+
p[0] = 0x3d600000 | (uint32_t)(desc_addr >> 48);\
239+
p[1] = 0x616b0000 | (uint32_t)((desc_addr >> 32) & 0xFFFF);\
240+
p[2] = 0x796b07c6 | (uint32_t)(32 << 21) | (31 << 16);\
241+
p[3] = 0x616b0000 | (uint32_t)((desc_addr >> 16) & 0xFFFF);\
242+
p[4] = 0x616b0000 | (uint32_t)(desc_addr & 0xFFFF);\
243+
/* ld r12, 0(r11) */ \
244+
p[5] = 0xe98b0000;\
245+
/* ld r2, 8(r11) */ \
246+
p[6] = 0xe84b0008;\
247+
/* mtctr r12 */ \
248+
p[7] = 0x7d8903a6;\
249+
/* bctr */ \
250+
p[8] = 0x4e800420;\
251+
CACHEFLUSH((char *)fn, CODESIZE);\
252+
} while(0)
253+
#define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub)
254+
207255
#elif defined(__powerpc64__)
208256
#define CODESIZE 28U
209257
#define CODESIZE_MIN 28U

0 commit comments

Comments
 (0)