@@ -165,9 +165,12 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *,
165
165
#undef ELFDATA2MSB
166
166
#undef EV_CURRENT
167
167
#undef ET_DYN
168
+ #undef EM_PPC64
169
+ #undef EF_PPC64_ABI
168
170
#undef SHN_LORESERVE
169
171
#undef SHN_XINDEX
170
172
#undef SHN_UNDEF
173
+ #undef SHT_PROGBITS
171
174
#undef SHT_SYMTAB
172
175
#undef SHT_STRTAB
173
176
#undef SHT_DYNSYM
@@ -245,6 +248,9 @@ typedef struct {
245
248
246
249
#define ET_DYN 3
247
250
251
+ #define EM_PPC64 21
252
+ #define EF_PPC64_ABI 3
253
+
248
254
typedef struct {
249
255
b_elf_word sh_name ; /* Section name, index in string tbl */
250
256
b_elf_word sh_type ; /* Type of section */
@@ -262,6 +268,7 @@ typedef struct {
262
268
#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
263
269
#define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */
264
270
271
+ #define SHT_PROGBITS 1
265
272
#define SHT_SYMTAB 2
266
273
#define SHT_STRTAB 3
267
274
#define SHT_DYNSYM 11
@@ -405,6 +412,20 @@ struct elf_syminfo_data
405
412
size_t count ;
406
413
};
407
414
415
+ /* Information about PowerPC64 ELFv1 .opd section. */
416
+
417
+ struct elf_ppc64_opd_data
418
+ {
419
+ /* Address of the .opd section. */
420
+ b_elf_addr addr ;
421
+ /* Section data. */
422
+ const char * data ;
423
+ /* Size of the .opd section. */
424
+ size_t size ;
425
+ /* Corresponding section view. */
426
+ struct backtrace_view view ;
427
+ };
428
+
408
429
/* Compute the CRC-32 of BUF/LEN. This uses the CRC used for
409
430
.gnu_debuglink files. */
410
431
@@ -569,7 +590,8 @@ elf_initialize_syminfo (struct backtrace_state *state,
569
590
const unsigned char * symtab_data , size_t symtab_size ,
570
591
const unsigned char * strtab , size_t strtab_size ,
571
592
backtrace_error_callback error_callback ,
572
- void * data , struct elf_syminfo_data * sdata )
593
+ void * data , struct elf_syminfo_data * sdata ,
594
+ struct elf_ppc64_opd_data * opd )
573
595
{
574
596
size_t sym_count ;
575
597
const b_elf_sym * sym ;
@@ -620,7 +642,17 @@ elf_initialize_syminfo (struct backtrace_state *state,
620
642
return 0 ;
621
643
}
622
644
elf_symbols [j ].name = (const char * ) strtab + sym -> st_name ;
623
- elf_symbols [j ].address = sym -> st_value + base_address ;
645
+ /* Special case PowerPC64 ELFv1 symbols in .opd section, if the symbol
646
+ is a function descriptor, read the actual code address from the
647
+ descriptor. */
648
+ if (opd
649
+ && sym -> st_value >= opd -> addr
650
+ && sym -> st_value < opd -> addr + opd -> size )
651
+ elf_symbols [j ].address
652
+ = * (const b_elf_addr * ) (opd -> data + (sym -> st_value - opd -> addr ));
653
+ else
654
+ elf_symbols [j ].address = sym -> st_value ;
655
+ elf_symbols [j ].address += base_address ;
624
656
elf_symbols [j ].size = sym -> st_size ;
625
657
++ j ;
626
658
}
@@ -1054,12 +1086,19 @@ elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend,
1054
1086
return 0 ;
1055
1087
}
1056
1088
1089
+ #if defined(__BYTE_ORDER__ ) && defined(__ORDER_LITTLE_ENDIAN__ ) \
1090
+ && defined(__ORDER_BIG_ENDIAN__ ) \
1091
+ && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ \
1092
+ || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
1057
1093
/* We've ensured that PIN is aligned. */
1058
1094
next = * (const uint32_t * )pin ;
1059
1095
1060
- #if __BYTE_ORDER == __ORDER_BIG_ENDIAN
1096
+ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1061
1097
next = __builtin_bswap32 (next );
1062
1098
#endif
1099
+ #else
1100
+ next = pin [0 ] | (pin [1 ] << 8 ) | (pin [2 ] << 16 ) | (pin [3 ] << 24 );
1101
+ #endif
1063
1102
1064
1103
val |= (uint64_t )next << bits ;
1065
1104
bits += 32 ;
@@ -2637,6 +2676,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
2637
2676
int debug_view_valid ;
2638
2677
unsigned int using_debug_view ;
2639
2678
uint16_t * zdebug_table ;
2679
+ struct elf_ppc64_opd_data opd_data , * opd ;
2640
2680
2641
2681
if (!debuginfo )
2642
2682
{
@@ -2655,6 +2695,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
2655
2695
debuglink_name = NULL ;
2656
2696
debuglink_crc = 0 ;
2657
2697
debug_view_valid = 0 ;
2698
+ opd = NULL ;
2658
2699
2659
2700
if (!backtrace_get_view (state , descriptor , 0 , sizeof ehdr , error_callback ,
2660
2701
data , & ehdr_view ))
@@ -2857,6 +2898,23 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
2857
2898
debuglink_crc = * (const uint32_t * )(debuglink_data + crc_offset );
2858
2899
}
2859
2900
}
2901
+
2902
+ /* Read the .opd section on PowerPC64 ELFv1. */
2903
+ if (ehdr .e_machine == EM_PPC64
2904
+ && (ehdr .e_flags & EF_PPC64_ABI ) < 2
2905
+ && shdr -> sh_type == SHT_PROGBITS
2906
+ && strcmp (name , ".opd" ) == 0 )
2907
+ {
2908
+ if (!backtrace_get_view (state , descriptor , shdr -> sh_offset ,
2909
+ shdr -> sh_size , error_callback , data ,
2910
+ & opd_data .view ))
2911
+ goto fail ;
2912
+
2913
+ opd = & opd_data ;
2914
+ opd -> addr = shdr -> sh_addr ;
2915
+ opd -> data = (const char * ) opd_data .view .data ;
2916
+ opd -> size = shdr -> sh_size ;
2917
+ }
2860
2918
}
2861
2919
2862
2920
if (symtab_shndx == 0 )
@@ -2898,7 +2956,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
2898
2956
if (!elf_initialize_syminfo (state , base_address ,
2899
2957
symtab_view .data , symtab_shdr -> sh_size ,
2900
2958
strtab_view .data , strtab_shdr -> sh_size ,
2901
- error_callback , data , sdata ))
2959
+ error_callback , data , sdata , opd ))
2902
2960
{
2903
2961
backtrace_free (state , sdata , sizeof * sdata , error_callback , data );
2904
2962
goto fail ;
@@ -2951,6 +3009,12 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
2951
3009
buildid_view_valid = 0 ;
2952
3010
}
2953
3011
3012
+ if (opd )
3013
+ {
3014
+ backtrace_release_view (state , & opd -> view , error_callback , data );
3015
+ opd = NULL ;
3016
+ }
3017
+
2954
3018
if (debuglink_name != NULL )
2955
3019
{
2956
3020
int d ;
@@ -3139,6 +3203,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
3139
3203
backtrace_release_view (state , & buildid_view , error_callback , data );
3140
3204
if (debug_view_valid )
3141
3205
backtrace_release_view (state , & debug_view , error_callback , data );
3206
+ if (opd )
3207
+ backtrace_release_view (state , & opd -> view , error_callback , data );
3142
3208
if (descriptor != -1 )
3143
3209
backtrace_close (descriptor , error_callback , data );
3144
3210
return 0 ;
0 commit comments