Skip to content

Commit d2e8ea4

Browse files
sandip4nyonghong-song
authored andcommitted
Fix ELF ABI and endianness checks for powerpc64
Earlier, it was assumed that ELF ABI v2 is used only on little-endian powerpc64 environments but it seems this ABI can be used independently of endianness. It is expected that any C preprocessor that conforms to the ELF ABI v2 specification must predefine the _CALL_ELF macro and set its value to 2. Instead of looking at __BYTE_ORDER__ to determine whether to use the Local Entry Point (LEP) of symbols, one should look at the _CALL_ELF macro instead as this is ABI-related. Similarly, _CALL_ELF should be used only for determining the ABI version and not the endianness. Reported-by: Naveen N. Rao <[email protected]> Fixes: bbd4180 ("Fix uprobes on powerpc64") Fixes: 1086952 ("clang: Add support to build eBPF for user specified ARCH") Acked-by: Naveen N. Rao <[email protected]> Signed-off-by: Sandipan Das <[email protected]>
1 parent ceb458d commit d2e8ea4

File tree

5 files changed

+18
-18
lines changed

5 files changed

+18
-18
lines changed

src/cc/bcc_elf.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -257,16 +257,8 @@ static int list_in_scn(Elf *e, Elf_Scn *section, size_t stridx, size_t symsize,
257257
continue;
258258

259259
#ifdef __powerpc64__
260-
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
261-
if (opddata && sym.st_shndx == opdidx) {
262-
size_t offset = sym.st_value - opdshdr.sh_addr;
263-
/* Find the function descriptor */
264-
uint64_t *descr = opddata->d_buf + offset;
265-
/* Read the actual entry point address from the descriptor */
266-
sym.st_value = *descr;
267-
}
268-
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
269-
if (option->use_symbol_type & (1 << STT_PPC64LE_SYM_LEP)) {
260+
#if defined(_CALL_ELF) && _CALL_ELF == 2
261+
if (option->use_symbol_type & (1 << STT_PPC64_ELFV2_SYM_LEP)) {
270262
/*
271263
* The PowerPC 64-bit ELF v2 ABI says that the 3 most significant bits
272264
* in the st_other field of the symbol table specifies the number of
@@ -287,6 +279,14 @@ static int list_in_scn(Elf *e, Elf_Scn *section, size_t stridx, size_t symsize,
287279
case 6: sym.st_value += 64; break;
288280
}
289281
}
282+
#else
283+
if (opddata && sym.st_shndx == opdidx) {
284+
size_t offset = sym.st_value - opdshdr.sh_addr;
285+
/* Find the function descriptor */
286+
uint64_t *descr = opddata->d_buf + offset;
287+
/* Read the actual entry point address from the descriptor */
288+
sym.st_value = *descr;
289+
}
290290
#endif
291291
#endif
292292

src/cc/bcc_syms.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,8 +712,8 @@ int bcc_resolve_symname(const char *module, const char *symname,
712712
.use_debug_file = 1,
713713
.check_debug_file_crc = 1,
714714
.lazy_symbolize = 1,
715-
#if defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
716-
.use_symbol_type = BCC_SYM_ALL_TYPES | (1 << STT_PPC64LE_SYM_LEP),
715+
#if defined(__powerpc64__) && defined(_CALL_ELF) && _CALL_ELF == 2
716+
.use_symbol_type = BCC_SYM_ALL_TYPES | (1 << STT_PPC64_ELFV2_SYM_LEP),
717717
#else
718718
.use_symbol_type = BCC_SYM_ALL_TYPES,
719719
#endif

src/cc/bcc_syms.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ struct mod_info;
3838
#define STT_GNU_IFUNC 10
3939
#endif
4040

41-
#if defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
41+
#if defined(__powerpc64__) && defined(_CALL_ELF) && _CALL_ELF == 2
4242
// Indicate if the Local Entry Point (LEP) should be used as a symbol's
4343
// start address
44-
#define STT_PPC64LE_SYM_LEP 31
44+
#define STT_PPC64_ELFV2_SYM_LEP 31
4545
#endif
4646

4747
static const uint32_t BCC_SYM_ALL_TYPES = 65535;

src/cc/frontends/clang/arch_helper.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ static void *run_arch_callback(arch_callback_t fn)
3434
/* If ARCH is not set, detect from local arch clang is running on */
3535
if (!archenv) {
3636
#if defined(__powerpc64__)
37-
#if defined(_CALL_ELF) && _CALL_ELF == 2
37+
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
3838
return fn(BCC_ARCH_PPC_LE);
3939
#else
4040
return fn(BCC_ARCH_PPC);
@@ -50,7 +50,7 @@ static void *run_arch_callback(arch_callback_t fn)
5050

5151
/* Otherwise read it from ARCH */
5252
if (!strcmp(archenv, "powerpc")) {
53-
#if defined(_CALL_ELF) && _CALL_ELF == 2
53+
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
5454
return fn(BCC_ARCH_PPC_LE);
5555
#else
5656
return fn(BCC_ARCH_PPC);

tests/cc/test_c_api.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,8 @@ TEST_CASE("resolve symbol addresses for a given PID", "[c_api]") {
205205
.use_debug_file = 1,
206206
.check_debug_file_crc = 1,
207207
.lazy_symbolize = 1,
208-
#if defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
209-
.use_symbol_type = BCC_SYM_ALL_TYPES | (1 << STT_PPC64LE_SYM_LEP),
208+
#if defined(__powerpc64__) && defined(_CALL_ELF) && _CALL_ELF == 2
209+
.use_symbol_type = BCC_SYM_ALL_TYPES | (1 << STT_PPC64_ELFV2_SYM_LEP),
210210
#else
211211
.use_symbol_type = BCC_SYM_ALL_TYPES,
212212
#endif

0 commit comments

Comments
 (0)