|
2 | 2 | #include <test_progs.h> |
3 | 3 | #include "test_attach_probe.skel.h" |
4 | 4 |
|
| 5 | +#if defined(__powerpc64__) && defined(_CALL_ELF) && _CALL_ELF == 2 |
| 6 | + |
| 7 | +#define OP_RT_RA_MASK 0xffff0000UL |
| 8 | +#define LIS_R2 0x3c400000UL |
| 9 | +#define ADDIS_R2_R12 0x3c4c0000UL |
| 10 | +#define ADDI_R2_R2 0x38420000UL |
| 11 | + |
| 12 | +static ssize_t get_offset(ssize_t addr, ssize_t base) |
| 13 | +{ |
| 14 | + u32 *insn = (u32 *) addr; |
| 15 | + |
| 16 | + /* |
| 17 | + * A PPC64 ABIv2 function may have a local and a global entry |
| 18 | + * point. We need to use the local entry point when patching |
| 19 | + * functions, so identify and step over the global entry point |
| 20 | + * sequence. |
| 21 | + * |
| 22 | + * The global entry point sequence is always of the form: |
| 23 | + * |
| 24 | + * addis r2,r12,XXXX |
| 25 | + * addi r2,r2,XXXX |
| 26 | + * |
| 27 | + * A linker optimisation may convert the addis to lis: |
| 28 | + * |
| 29 | + * lis r2,XXXX |
| 30 | + * addi r2,r2,XXXX |
| 31 | + */ |
| 32 | + if ((((*insn & OP_RT_RA_MASK) == ADDIS_R2_R12) || |
| 33 | + ((*insn & OP_RT_RA_MASK) == LIS_R2)) && |
| 34 | + ((*(insn + 1) & OP_RT_RA_MASK) == ADDI_R2_R2)) |
| 35 | + return (ssize_t)(insn + 2) - base; |
| 36 | + else |
| 37 | + return addr - base; |
| 38 | +} |
| 39 | +#else |
| 40 | + |
| 41 | +static ssize_t get_offset(ssize_t addr, ssize_t base) |
| 42 | +{ |
| 43 | + return addr - base; |
| 44 | +} |
| 45 | + |
| 46 | +#endif |
| 47 | + |
5 | 48 | ssize_t get_base_addr() { |
6 | 49 | size_t start, offset; |
7 | 50 | char buf[256]; |
@@ -36,7 +79,7 @@ void test_attach_probe(void) |
36 | 79 | if (CHECK(base_addr < 0, "get_base_addr", |
37 | 80 | "failed to find base addr: %zd", base_addr)) |
38 | 81 | return; |
39 | | - uprobe_offset = (size_t)&get_base_addr - base_addr; |
| 82 | + uprobe_offset = get_offset((size_t)&get_base_addr, base_addr); |
40 | 83 |
|
41 | 84 | skel = test_attach_probe__open_and_load(); |
42 | 85 | if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) |
|
0 commit comments