1 /*- 2 * Copyright (c) 2009-2015 Kai Wang 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/param.h> 28 #include <sys/queue.h> 29 #include <ar.h> 30 #include <ctype.h> 31 #include <dwarf.h> 32 #include <err.h> 33 #include <fcntl.h> 34 #include <gelf.h> 35 #include <getopt.h> 36 #include <libdwarf.h> 37 #include <libelftc.h> 38 #include <libgen.h> 39 #include <stdarg.h> 40 #include <stdint.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <time.h> 45 #include <unistd.h> 46 47 #include "_elftc.h" 48 49 ELFTC_VCSID("$Id: readelf.c 3223 2015-05-25 20:37:57Z emaste $"); 50 51 /* 52 * readelf(1) options. 53 */ 54 #define RE_AA 0x00000001 55 #define RE_C 0x00000002 56 #define RE_DD 0x00000004 57 #define RE_D 0x00000008 58 #define RE_G 0x00000010 59 #define RE_H 0x00000020 60 #define RE_II 0x00000040 61 #define RE_I 0x00000080 62 #define RE_L 0x00000100 63 #define RE_NN 0x00000200 64 #define RE_N 0x00000400 65 #define RE_P 0x00000800 66 #define RE_R 0x00001000 67 #define RE_SS 0x00002000 68 #define RE_S 0x00004000 69 #define RE_T 0x00008000 70 #define RE_U 0x00010000 71 #define RE_VV 0x00020000 72 #define RE_WW 0x00040000 73 #define RE_W 0x00080000 74 #define RE_X 0x00100000 75 76 /* 77 * dwarf dump options. 78 */ 79 #define DW_A 0x00000001 80 #define DW_FF 0x00000002 81 #define DW_F 0x00000004 82 #define DW_I 0x00000008 83 #define DW_LL 0x00000010 84 #define DW_L 0x00000020 85 #define DW_M 0x00000040 86 #define DW_O 0x00000080 87 #define DW_P 0x00000100 88 #define DW_RR 0x00000200 89 #define DW_R 0x00000400 90 #define DW_S 0x00000800 91 92 #define DW_DEFAULT_OPTIONS (DW_A | DW_F | DW_I | DW_L | DW_O | DW_P | \ 93 DW_R | DW_RR | DW_S) 94 95 /* 96 * readelf(1) run control flags. 97 */ 98 #define DISPLAY_FILENAME 0x0001 99 100 /* 101 * Internal data structure for sections. 102 */ 103 struct section { 104 const char *name; /* section name */ 105 Elf_Scn *scn; /* section scn */ 106 uint64_t off; /* section offset */ 107 uint64_t sz; /* section size */ 108 uint64_t entsize; /* section entsize */ 109 uint64_t align; /* section alignment */ 110 uint64_t type; /* section type */ 111 uint64_t flags; /* section flags */ 112 uint64_t addr; /* section virtual addr */ 113 uint32_t link; /* section link ndx */ 114 uint32_t info; /* section info ndx */ 115 }; 116 117 struct dumpop { 118 union { 119 size_t si; /* section index */ 120 const char *sn; /* section name */ 121 } u; 122 enum { 123 DUMP_BY_INDEX = 0, 124 DUMP_BY_NAME 125 } type; /* dump type */ 126 #define HEX_DUMP 0x0001 127 #define STR_DUMP 0x0002 128 int op; /* dump operation */ 129 STAILQ_ENTRY(dumpop) dumpop_list; 130 }; 131 132 struct symver { 133 const char *name; 134 int type; 135 }; 136 137 /* 138 * Structure encapsulates the global data for readelf(1). 139 */ 140 struct readelf { 141 const char *filename; /* current processing file. */ 142 int options; /* command line options. */ 143 int flags; /* run control flags. */ 144 int dop; /* dwarf dump options. */ 145 Elf *elf; /* underlying ELF descriptor. */ 146 Elf *ar; /* archive ELF descriptor. */ 147 Dwarf_Debug dbg; /* DWARF handle. */ 148 Dwarf_Half cu_psize; /* DWARF CU pointer size. */ 149 Dwarf_Half cu_osize; /* DWARF CU offset size. */ 150 Dwarf_Half cu_ver; /* DWARF CU version. */ 151 GElf_Ehdr ehdr; /* ELF header. */ 152 int ec; /* ELF class. */ 153 size_t shnum; /* #sections. */ 154 struct section *vd_s; /* Verdef section. */ 155 struct section *vn_s; /* Verneed section. */ 156 struct section *vs_s; /* Versym section. */ 157 uint16_t *vs; /* Versym array. */ 158 int vs_sz; /* Versym array size. */ 159 struct symver *ver; /* Version array. */ 160 int ver_sz; /* Size of version array. */ 161 struct section *sl; /* list of sections. */ 162 STAILQ_HEAD(, dumpop) v_dumpop; /* list of dump ops. */ 163 uint64_t (*dw_read)(Elf_Data *, uint64_t *, int); 164 uint64_t (*dw_decode)(uint8_t **, int); 165 }; 166 167 enum options 168 { 169 OPTION_DEBUG_DUMP 170 }; 171 172 static struct option longopts[] = { 173 {"all", no_argument, NULL, 'a'}, 174 {"arch-specific", no_argument, NULL, 'A'}, 175 {"archive-index", no_argument, NULL, 'c'}, 176 {"debug-dump", optional_argument, NULL, OPTION_DEBUG_DUMP}, 177 {"dynamic", no_argument, NULL, 'd'}, 178 {"file-header", no_argument, NULL, 'h'}, 179 {"full-section-name", no_argument, NULL, 'N'}, 180 {"headers", no_argument, NULL, 'e'}, 181 {"help", no_argument, 0, 'H'}, 182 {"hex-dump", required_argument, NULL, 'x'}, 183 {"histogram", no_argument, NULL, 'I'}, 184 {"notes", no_argument, NULL, 'n'}, 185 {"program-headers", no_argument, NULL, 'l'}, 186 {"relocs", no_argument, NULL, 'r'}, 187 {"sections", no_argument, NULL, 'S'}, 188 {"section-headers", no_argument, NULL, 'S'}, 189 {"section-groups", no_argument, NULL, 'g'}, 190 {"section-details", no_argument, NULL, 't'}, 191 {"segments", no_argument, NULL, 'l'}, 192 {"string-dump", required_argument, NULL, 'p'}, 193 {"symbols", no_argument, NULL, 's'}, 194 {"syms", no_argument, NULL, 's'}, 195 {"unwind", no_argument, NULL, 'u'}, 196 {"use-dynamic", no_argument, NULL, 'D'}, 197 {"version-info", no_argument, 0, 'V'}, 198 {"version", no_argument, 0, 'v'}, 199 {"wide", no_argument, 0, 'W'}, 200 {NULL, 0, NULL, 0} 201 }; 202 203 struct eflags_desc { 204 uint64_t flag; 205 const char *desc; 206 }; 207 208 struct mips_option { 209 uint64_t flag; 210 const char *desc; 211 }; 212 213 static void add_dumpop(struct readelf *re, size_t si, const char *sn, int op, 214 int t); 215 static const char *aeabi_adv_simd_arch(uint64_t simd); 216 static const char *aeabi_align_needed(uint64_t an); 217 static const char *aeabi_align_preserved(uint64_t ap); 218 static const char *aeabi_arm_isa(uint64_t ai); 219 static const char *aeabi_cpu_arch(uint64_t arch); 220 static const char *aeabi_cpu_arch_profile(uint64_t pf); 221 static const char *aeabi_div(uint64_t du); 222 static const char *aeabi_enum_size(uint64_t es); 223 static const char *aeabi_fp_16bit_format(uint64_t fp16); 224 static const char *aeabi_fp_arch(uint64_t fp); 225 static const char *aeabi_fp_denormal(uint64_t fd); 226 static const char *aeabi_fp_exceptions(uint64_t fe); 227 static const char *aeabi_fp_hpext(uint64_t fh); 228 static const char *aeabi_fp_number_model(uint64_t fn); 229 static const char *aeabi_fp_optm_goal(uint64_t fog); 230 static const char *aeabi_fp_rounding(uint64_t fr); 231 static const char *aeabi_hardfp(uint64_t hfp); 232 static const char *aeabi_mpext(uint64_t mp); 233 static const char *aeabi_optm_goal(uint64_t og); 234 static const char *aeabi_pcs_config(uint64_t pcs); 235 static const char *aeabi_pcs_got(uint64_t got); 236 static const char *aeabi_pcs_r9(uint64_t r9); 237 static const char *aeabi_pcs_ro(uint64_t ro); 238 static const char *aeabi_pcs_rw(uint64_t rw); 239 static const char *aeabi_pcs_wchar_t(uint64_t wt); 240 static const char *aeabi_t2ee(uint64_t t2ee); 241 static const char *aeabi_thumb_isa(uint64_t ti); 242 static const char *aeabi_fp_user_exceptions(uint64_t fu); 243 static const char *aeabi_unaligned_access(uint64_t ua); 244 static const char *aeabi_vfp_args(uint64_t va); 245 static const char *aeabi_virtual(uint64_t vt); 246 static const char *aeabi_wmmx_arch(uint64_t wmmx); 247 static const char *aeabi_wmmx_args(uint64_t wa); 248 static const char *elf_class(unsigned int class); 249 static const char *elf_endian(unsigned int endian); 250 static const char *elf_machine(unsigned int mach); 251 static const char *elf_osabi(unsigned int abi); 252 static const char *elf_type(unsigned int type); 253 static const char *elf_ver(unsigned int ver); 254 static const char *dt_type(unsigned int mach, unsigned int dtype); 255 static void dump_ar(struct readelf *re, int); 256 static void dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe); 257 static void dump_attributes(struct readelf *re); 258 static uint8_t *dump_compatibility_tag(uint8_t *p); 259 static void dump_dwarf(struct readelf *re); 260 static void dump_dwarf_abbrev(struct readelf *re); 261 static void dump_dwarf_aranges(struct readelf *re); 262 static void dump_dwarf_block(struct readelf *re, uint8_t *b, 263 Dwarf_Unsigned len); 264 static void dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level); 265 static void dump_dwarf_frame(struct readelf *re, int alt); 266 static void dump_dwarf_frame_inst(struct readelf *re, Dwarf_Cie cie, 267 uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, 268 Dwarf_Addr pc, Dwarf_Debug dbg); 269 static int dump_dwarf_frame_regtable(struct readelf *re, Dwarf_Fde fde, 270 Dwarf_Addr pc, Dwarf_Unsigned func_len, Dwarf_Half cie_ra); 271 static void dump_dwarf_frame_section(struct readelf *re, struct section *s, 272 int alt); 273 static void dump_dwarf_info(struct readelf *re, Dwarf_Bool is_info); 274 static void dump_dwarf_macinfo(struct readelf *re); 275 static void dump_dwarf_line(struct readelf *re); 276 static void dump_dwarf_line_decoded(struct readelf *re); 277 static void dump_dwarf_loc(struct readelf *re, Dwarf_Loc *lr); 278 static void dump_dwarf_loclist(struct readelf *re); 279 static void dump_dwarf_pubnames(struct readelf *re); 280 static void dump_dwarf_ranges(struct readelf *re); 281 static void dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die, 282 Dwarf_Addr base); 283 static void dump_dwarf_str(struct readelf *re); 284 static void dump_eflags(struct readelf *re, uint64_t e_flags); 285 static void dump_elf(struct readelf *re); 286 static void dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab); 287 static void dump_dynamic(struct readelf *re); 288 static void dump_liblist(struct readelf *re); 289 static void dump_mips_attributes(struct readelf *re, uint8_t *p, uint8_t *pe); 290 static void dump_mips_odk_reginfo(struct readelf *re, uint8_t *p, size_t sz); 291 static void dump_mips_options(struct readelf *re, struct section *s); 292 static void dump_mips_option_flags(const char *name, struct mips_option *opt, 293 uint64_t info); 294 static void dump_mips_reginfo(struct readelf *re, struct section *s); 295 static void dump_mips_specific_info(struct readelf *re); 296 static void dump_notes(struct readelf *re); 297 static void dump_notes_content(struct readelf *re, const char *buf, size_t sz, 298 off_t off); 299 static void dump_svr4_hash(struct section *s); 300 static void dump_svr4_hash64(struct readelf *re, struct section *s); 301 static void dump_gnu_hash(struct readelf *re, struct section *s); 302 static void dump_hash(struct readelf *re); 303 static void dump_phdr(struct readelf *re); 304 static void dump_ppc_attributes(uint8_t *p, uint8_t *pe); 305 static void dump_section_groups(struct readelf *re); 306 static void dump_symtab(struct readelf *re, int i); 307 static void dump_symtabs(struct readelf *re); 308 static uint8_t *dump_unknown_tag(uint64_t tag, uint8_t *p); 309 static void dump_ver(struct readelf *re); 310 static void dump_verdef(struct readelf *re, int dump); 311 static void dump_verneed(struct readelf *re, int dump); 312 static void dump_versym(struct readelf *re); 313 static const char *dwarf_reg(unsigned int mach, unsigned int reg); 314 static const char *dwarf_regname(struct readelf *re, unsigned int num); 315 static struct dumpop *find_dumpop(struct readelf *re, size_t si, 316 const char *sn, int op, int t); 317 static char *get_regoff_str(struct readelf *re, Dwarf_Half reg, 318 Dwarf_Addr off); 319 static const char *get_string(struct readelf *re, int strtab, size_t off); 320 static const char *get_symbol_name(struct readelf *re, int symtab, int i); 321 static uint64_t get_symbol_value(struct readelf *re, int symtab, int i); 322 static void load_sections(struct readelf *re); 323 static const char *mips_abi_fp(uint64_t fp); 324 static const char *note_type(const char *note_name, unsigned int et, 325 unsigned int nt); 326 static const char *note_type_freebsd(unsigned int nt); 327 static const char *note_type_freebsd_core(unsigned int nt); 328 static const char *note_type_linux_core(unsigned int nt); 329 static const char *note_type_gnu(unsigned int nt); 330 static const char *note_type_netbsd(unsigned int nt); 331 static const char *note_type_openbsd(unsigned int nt); 332 static const char *note_type_unknown(unsigned int nt); 333 static const char *option_kind(uint8_t kind); 334 static const char *phdr_type(unsigned int ptype); 335 static const char *ppc_abi_fp(uint64_t fp); 336 static const char *ppc_abi_vector(uint64_t vec); 337 static const char *r_type(unsigned int mach, unsigned int type); 338 static void readelf_usage(void); 339 static void readelf_version(void); 340 static void search_loclist_at(struct readelf *re, Dwarf_Die die, 341 Dwarf_Unsigned lowpc); 342 static void search_ver(struct readelf *re); 343 static const char *section_type(unsigned int mach, unsigned int stype); 344 static void set_cu_context(struct readelf *re, Dwarf_Half psize, 345 Dwarf_Half osize, Dwarf_Half ver); 346 static const char *st_bind(unsigned int sbind); 347 static const char *st_shndx(unsigned int shndx); 348 static const char *st_type(unsigned int stype); 349 static const char *st_vis(unsigned int svis); 350 static const char *top_tag(unsigned int tag); 351 static void unload_sections(struct readelf *re); 352 static uint64_t _read_lsb(Elf_Data *d, uint64_t *offsetp, 353 int bytes_to_read); 354 static uint64_t _read_msb(Elf_Data *d, uint64_t *offsetp, 355 int bytes_to_read); 356 static uint64_t _decode_lsb(uint8_t **data, int bytes_to_read); 357 static uint64_t _decode_msb(uint8_t **data, int bytes_to_read); 358 static int64_t _decode_sleb128(uint8_t **dp); 359 static uint64_t _decode_uleb128(uint8_t **dp); 360 361 static struct eflags_desc arm_eflags_desc[] = { 362 {EF_ARM_RELEXEC, "relocatable executable"}, 363 {EF_ARM_HASENTRY, "has entry point"}, 364 {EF_ARM_SYMSARESORTED, "sorted symbol tables"}, 365 {EF_ARM_DYNSYMSUSESEGIDX, "dynamic symbols use segment index"}, 366 {EF_ARM_MAPSYMSFIRST, "mapping symbols precede others"}, 367 {EF_ARM_BE8, "BE8"}, 368 {EF_ARM_LE8, "LE8"}, 369 {EF_ARM_INTERWORK, "interworking enabled"}, 370 {EF_ARM_APCS_26, "uses APCS/26"}, 371 {EF_ARM_APCS_FLOAT, "uses APCS/float"}, 372 {EF_ARM_PIC, "position independent"}, 373 {EF_ARM_ALIGN8, "8 bit structure alignment"}, 374 {EF_ARM_NEW_ABI, "uses new ABI"}, 375 {EF_ARM_OLD_ABI, "uses old ABI"}, 376 {EF_ARM_SOFT_FLOAT, "software FP"}, 377 {EF_ARM_VFP_FLOAT, "VFP"}, 378 {EF_ARM_MAVERICK_FLOAT, "Maverick FP"}, 379 {0, NULL} 380 }; 381 382 static struct eflags_desc mips_eflags_desc[] = { 383 {EF_MIPS_NOREORDER, "noreorder"}, 384 {EF_MIPS_PIC, "pic"}, 385 {EF_MIPS_CPIC, "cpic"}, 386 {EF_MIPS_UCODE, "ugen_reserved"}, 387 {EF_MIPS_ABI2, "abi2"}, 388 {EF_MIPS_OPTIONS_FIRST, "odk first"}, 389 {EF_MIPS_ARCH_ASE_MDMX, "mdmx"}, 390 {EF_MIPS_ARCH_ASE_M16, "mips16"}, 391 {0, NULL} 392 }; 393 394 static struct eflags_desc powerpc_eflags_desc[] = { 395 {EF_PPC_EMB, "emb"}, 396 {EF_PPC_RELOCATABLE, "relocatable"}, 397 {EF_PPC_RELOCATABLE_LIB, "relocatable-lib"}, 398 {0, NULL} 399 }; 400 401 static struct eflags_desc sparc_eflags_desc[] = { 402 {EF_SPARC_32PLUS, "v8+"}, 403 {EF_SPARC_SUN_US1, "ultrasparcI"}, 404 {EF_SPARC_HAL_R1, "halr1"}, 405 {EF_SPARC_SUN_US3, "ultrasparcIII"}, 406 {0, NULL} 407 }; 408 409 static const char * 410 elf_osabi(unsigned int abi) 411 { 412 static char s_abi[32]; 413 414 switch(abi) { 415 case ELFOSABI_SYSV: return "SYSV"; 416 case ELFOSABI_HPUX: return "HPUS"; 417 case ELFOSABI_NETBSD: return "NetBSD"; 418 case ELFOSABI_GNU: return "GNU"; 419 case ELFOSABI_HURD: return "HURD"; 420 case ELFOSABI_86OPEN: return "86OPEN"; 421 case ELFOSABI_SOLARIS: return "Solaris"; 422 case ELFOSABI_AIX: return "AIX"; 423 case ELFOSABI_IRIX: return "IRIX"; 424 case ELFOSABI_FREEBSD: return "FreeBSD"; 425 case ELFOSABI_TRU64: return "TRU64"; 426 case ELFOSABI_MODESTO: return "MODESTO"; 427 case ELFOSABI_OPENBSD: return "OpenBSD"; 428 case ELFOSABI_OPENVMS: return "OpenVMS"; 429 case ELFOSABI_NSK: return "NSK"; 430 case ELFOSABI_ARM: return "ARM"; 431 case ELFOSABI_STANDALONE: return "StandAlone"; 432 default: 433 snprintf(s_abi, sizeof(s_abi), "<unknown: %#x>", abi); 434 return (s_abi); 435 } 436 }; 437 438 static const char * 439 elf_machine(unsigned int mach) 440 { 441 static char s_mach[32]; 442 443 switch (mach) { 444 case EM_NONE: return "Unknown machine"; 445 case EM_M32: return "AT&T WE32100"; 446 case EM_SPARC: return "Sun SPARC"; 447 case EM_386: return "Intel i386"; 448 case EM_68K: return "Motorola 68000"; 449 case EM_IAMCU: return "Intel MCU"; 450 case EM_88K: return "Motorola 88000"; 451 case EM_860: return "Intel i860"; 452 case EM_MIPS: return "MIPS R3000 Big-Endian only"; 453 case EM_S370: return "IBM System/370"; 454 case EM_MIPS_RS3_LE: return "MIPS R3000 Little-Endian"; 455 case EM_PARISC: return "HP PA-RISC"; 456 case EM_VPP500: return "Fujitsu VPP500"; 457 case EM_SPARC32PLUS: return "SPARC v8plus"; 458 case EM_960: return "Intel 80960"; 459 case EM_PPC: return "PowerPC 32-bit"; 460 case EM_PPC64: return "PowerPC 64-bit"; 461 case EM_S390: return "IBM System/390"; 462 case EM_V800: return "NEC V800"; 463 case EM_FR20: return "Fujitsu FR20"; 464 case EM_RH32: return "TRW RH-32"; 465 case EM_RCE: return "Motorola RCE"; 466 case EM_ARM: return "ARM"; 467 case EM_SH: return "Hitachi SH"; 468 case EM_SPARCV9: return "SPARC v9 64-bit"; 469 case EM_TRICORE: return "Siemens TriCore embedded processor"; 470 case EM_ARC: return "Argonaut RISC Core"; 471 case EM_H8_300: return "Hitachi H8/300"; 472 case EM_H8_300H: return "Hitachi H8/300H"; 473 case EM_H8S: return "Hitachi H8S"; 474 case EM_H8_500: return "Hitachi H8/500"; 475 case EM_IA_64: return "Intel IA-64 Processor"; 476 case EM_MIPS_X: return "Stanford MIPS-X"; 477 case EM_COLDFIRE: return "Motorola ColdFire"; 478 case EM_68HC12: return "Motorola M68HC12"; 479 case EM_MMA: return "Fujitsu MMA"; 480 case EM_PCP: return "Siemens PCP"; 481 case EM_NCPU: return "Sony nCPU"; 482 case EM_NDR1: return "Denso NDR1 microprocessor"; 483 case EM_STARCORE: return "Motorola Star*Core processor"; 484 case EM_ME16: return "Toyota ME16 processor"; 485 case EM_ST100: return "STMicroelectronics ST100 processor"; 486 case EM_TINYJ: return "Advanced Logic Corp. TinyJ processor"; 487 case EM_X86_64: return "Advanced Micro Devices x86-64"; 488 case EM_PDSP: return "Sony DSP Processor"; 489 case EM_FX66: return "Siemens FX66 microcontroller"; 490 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 microcontroller"; 491 case EM_ST7: return "STmicroelectronics ST7 8-bit microcontroller"; 492 case EM_68HC16: return "Motorola MC68HC16 microcontroller"; 493 case EM_68HC11: return "Motorola MC68HC11 microcontroller"; 494 case EM_68HC08: return "Motorola MC68HC08 microcontroller"; 495 case EM_68HC05: return "Motorola MC68HC05 microcontroller"; 496 case EM_SVX: return "Silicon Graphics SVx"; 497 case EM_ST19: return "STMicroelectronics ST19 8-bit mc"; 498 case EM_VAX: return "Digital VAX"; 499 case EM_CRIS: return "Axis Communications 32-bit embedded processor"; 500 case EM_JAVELIN: return "Infineon Tech. 32bit embedded processor"; 501 case EM_FIREPATH: return "Element 14 64-bit DSP Processor"; 502 case EM_ZSP: return "LSI Logic 16-bit DSP Processor"; 503 case EM_MMIX: return "Donald Knuth's educational 64-bit proc"; 504 case EM_HUANY: return "Harvard University MI object files"; 505 case EM_PRISM: return "SiTera Prism"; 506 case EM_AVR: return "Atmel AVR 8-bit microcontroller"; 507 case EM_FR30: return "Fujitsu FR30"; 508 case EM_D10V: return "Mitsubishi D10V"; 509 case EM_D30V: return "Mitsubishi D30V"; 510 case EM_V850: return "NEC v850"; 511 case EM_M32R: return "Mitsubishi M32R"; 512 case EM_MN10300: return "Matsushita MN10300"; 513 case EM_MN10200: return "Matsushita MN10200"; 514 case EM_PJ: return "picoJava"; 515 case EM_OPENRISC: return "OpenRISC 32-bit embedded processor"; 516 case EM_ARC_A5: return "ARC Cores Tangent-A5"; 517 case EM_XTENSA: return "Tensilica Xtensa Architecture"; 518 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor"; 519 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor"; 520 case EM_NS32K: return "National Semiconductor 32000 series"; 521 case EM_TPC: return "Tenor Network TPC processor"; 522 case EM_SNP1K: return "Trebia SNP 1000 processor"; 523 case EM_ST200: return "STMicroelectronics ST200 microcontroller"; 524 case EM_IP2K: return "Ubicom IP2xxx microcontroller family"; 525 case EM_MAX: return "MAX Processor"; 526 case EM_CR: return "National Semiconductor CompactRISC microprocessor"; 527 case EM_F2MC16: return "Fujitsu F2MC16"; 528 case EM_MSP430: return "TI embedded microcontroller msp430"; 529 case EM_BLACKFIN: return "Analog Devices Blackfin (DSP) processor"; 530 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors"; 531 case EM_SEP: return "Sharp embedded microprocessor"; 532 case EM_ARCA: return "Arca RISC Microprocessor"; 533 case EM_UNICORE: return "Microprocessor series from PKU-Unity Ltd"; 534 case EM_AARCH64: return "AArch64"; 535 default: 536 snprintf(s_mach, sizeof(s_mach), "<unknown: %#x>", mach); 537 return (s_mach); 538 } 539 540 } 541 542 static const char * 543 elf_class(unsigned int class) 544 { 545 static char s_class[32]; 546 547 switch (class) { 548 case ELFCLASSNONE: return "none"; 549 case ELFCLASS32: return "ELF32"; 550 case ELFCLASS64: return "ELF64"; 551 default: 552 snprintf(s_class, sizeof(s_class), "<unknown: %#x>", class); 553 return (s_class); 554 } 555 } 556 557 static const char * 558 elf_endian(unsigned int endian) 559 { 560 static char s_endian[32]; 561 562 switch (endian) { 563 case ELFDATANONE: return "none"; 564 case ELFDATA2LSB: return "2's complement, little endian"; 565 case ELFDATA2MSB: return "2's complement, big endian"; 566 default: 567 snprintf(s_endian, sizeof(s_endian), "<unknown: %#x>", endian); 568 return (s_endian); 569 } 570 } 571 572 static const char * 573 elf_type(unsigned int type) 574 { 575 static char s_type[32]; 576 577 switch (type) { 578 case ET_NONE: return "NONE (None)"; 579 case ET_REL: return "REL (Relocatable file)"; 580 case ET_EXEC: return "EXEC (Executable file)"; 581 case ET_DYN: return "DYN (Shared object file)"; 582 case ET_CORE: return "CORE (Core file)"; 583 default: 584 if (type >= ET_LOPROC) 585 snprintf(s_type, sizeof(s_type), "<proc: %#x>", type); 586 else if (type >= ET_LOOS && type <= ET_HIOS) 587 snprintf(s_type, sizeof(s_type), "<os: %#x>", type); 588 else 589 snprintf(s_type, sizeof(s_type), "<unknown: %#x>", 590 type); 591 return (s_type); 592 } 593 } 594 595 static const char * 596 elf_ver(unsigned int ver) 597 { 598 static char s_ver[32]; 599 600 switch (ver) { 601 case EV_CURRENT: return "(current)"; 602 case EV_NONE: return "(none)"; 603 default: 604 snprintf(s_ver, sizeof(s_ver), "<unknown: %#x>", 605 ver); 606 return (s_ver); 607 } 608 } 609 610 static const char * 611 phdr_type(unsigned int ptype) 612 { 613 static char s_ptype[32]; 614 615 switch (ptype) { 616 case PT_NULL: return "NULL"; 617 case PT_LOAD: return "LOAD"; 618 case PT_DYNAMIC: return "DYNAMIC"; 619 case PT_INTERP: return "INTERP"; 620 case PT_NOTE: return "NOTE"; 621 case PT_SHLIB: return "SHLIB"; 622 case PT_PHDR: return "PHDR"; 623 case PT_TLS: return "TLS"; 624 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME"; 625 case PT_GNU_STACK: return "GNU_STACK"; 626 case PT_GNU_RELRO: return "GNU_RELRO"; 627 default: 628 if (ptype >= PT_LOPROC && ptype <= PT_HIPROC) 629 snprintf(s_ptype, sizeof(s_ptype), "LOPROC+%#x", 630 ptype - PT_LOPROC); 631 else if (ptype >= PT_LOOS && ptype <= PT_HIOS) 632 snprintf(s_ptype, sizeof(s_ptype), "LOOS+%#x", 633 ptype - PT_LOOS); 634 else 635 snprintf(s_ptype, sizeof(s_ptype), "<unknown: %#x>", 636 ptype); 637 return (s_ptype); 638 } 639 } 640 641 static const char * 642 section_type(unsigned int mach, unsigned int stype) 643 { 644 static char s_stype[32]; 645 646 if (stype >= SHT_LOPROC && stype <= SHT_HIPROC) { 647 switch (mach) { 648 case EM_X86_64: 649 switch (stype) { 650 case SHT_AMD64_UNWIND: return "AMD64_UNWIND"; 651 default: 652 break; 653 } 654 break; 655 case EM_MIPS: 656 case EM_MIPS_RS3_LE: 657 switch (stype) { 658 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST"; 659 case SHT_MIPS_MSYM: return "MIPS_MSYM"; 660 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT"; 661 case SHT_MIPS_GPTAB: return "MIPS_GPTAB"; 662 case SHT_MIPS_UCODE: return "MIPS_UCODE"; 663 case SHT_MIPS_DEBUG: return "MIPS_DEBUG"; 664 case SHT_MIPS_REGINFO: return "MIPS_REGINFO"; 665 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE"; 666 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM"; 667 case SHT_MIPS_RELD: return "MIPS_RELD"; 668 case SHT_MIPS_IFACE: return "MIPS_IFACE"; 669 case SHT_MIPS_CONTENT: return "MIPS_CONTENT"; 670 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS"; 671 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM"; 672 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST"; 673 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS"; 674 case SHT_MIPS_DWARF: return "MIPS_DWARF"; 675 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL"; 676 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB"; 677 case SHT_MIPS_EVENTS: return "MIPS_EVENTS"; 678 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE"; 679 case SHT_MIPS_PIXIE: return "MIPS_PIXIE"; 680 case SHT_MIPS_XLATE: return "MIPS_XLATE"; 681 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG"; 682 case SHT_MIPS_WHIRL: return "MIPS_WHIRL"; 683 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION"; 684 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD"; 685 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION"; 686 default: 687 break; 688 } 689 break; 690 default: 691 break; 692 } 693 694 snprintf(s_stype, sizeof(s_stype), "LOPROC+%#x", 695 stype - SHT_LOPROC); 696 return (s_stype); 697 } 698 699 switch (stype) { 700 case SHT_NULL: return "NULL"; 701 case SHT_PROGBITS: return "PROGBITS"; 702 case SHT_SYMTAB: return "SYMTAB"; 703 case SHT_STRTAB: return "STRTAB"; 704 case SHT_RELA: return "RELA"; 705 case SHT_HASH: return "HASH"; 706 case SHT_DYNAMIC: return "DYNAMIC"; 707 case SHT_NOTE: return "NOTE"; 708 case SHT_NOBITS: return "NOBITS"; 709 case SHT_REL: return "REL"; 710 case SHT_SHLIB: return "SHLIB"; 711 case SHT_DYNSYM: return "DYNSYM"; 712 case SHT_INIT_ARRAY: return "INIT_ARRAY"; 713 case SHT_FINI_ARRAY: return "FINI_ARRAY"; 714 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY"; 715 case SHT_GROUP: return "GROUP"; 716 case SHT_SYMTAB_SHNDX: return "SYMTAB_SHNDX"; 717 case SHT_SUNW_dof: return "SUNW_dof"; 718 case SHT_SUNW_cap: return "SUNW_cap"; 719 case SHT_GNU_HASH: return "GNU_HASH"; 720 case SHT_SUNW_ANNOTATE: return "SUNW_ANNOTATE"; 721 case SHT_SUNW_DEBUGSTR: return "SUNW_DEBUGSTR"; 722 case SHT_SUNW_DEBUG: return "SUNW_DEBUG"; 723 case SHT_SUNW_move: return "SUNW_move"; 724 case SHT_SUNW_COMDAT: return "SUNW_COMDAT"; 725 case SHT_SUNW_syminfo: return "SUNW_syminfo"; 726 case SHT_SUNW_verdef: return "SUNW_verdef"; 727 case SHT_SUNW_verneed: return "SUNW_verneed"; 728 case SHT_SUNW_versym: return "SUNW_versym"; 729 default: 730 if (stype >= SHT_LOOS && stype <= SHT_HIOS) 731 snprintf(s_stype, sizeof(s_stype), "LOOS+%#x", 732 stype - SHT_LOOS); 733 else if (stype >= SHT_LOUSER) 734 snprintf(s_stype, sizeof(s_stype), "LOUSER+%#x", 735 stype - SHT_LOUSER); 736 else 737 snprintf(s_stype, sizeof(s_stype), "<unknown: %#x>", 738 stype); 739 return (s_stype); 740 } 741 } 742 743 static const char * 744 dt_type(unsigned int mach, unsigned int dtype) 745 { 746 static char s_dtype[32]; 747 748 if (dtype >= DT_LOPROC && dtype <= DT_HIPROC) { 749 switch (mach) { 750 case EM_ARM: 751 switch (dtype) { 752 case DT_ARM_SYMTABSZ: 753 return "ARM_SYMTABSZ"; 754 default: 755 break; 756 } 757 break; 758 case EM_MIPS: 759 case EM_MIPS_RS3_LE: 760 switch (dtype) { 761 case DT_MIPS_RLD_VERSION: 762 return "MIPS_RLD_VERSION"; 763 case DT_MIPS_TIME_STAMP: 764 return "MIPS_TIME_STAMP"; 765 case DT_MIPS_ICHECKSUM: 766 return "MIPS_ICHECKSUM"; 767 case DT_MIPS_IVERSION: 768 return "MIPS_IVERSION"; 769 case DT_MIPS_FLAGS: 770 return "MIPS_FLAGS"; 771 case DT_MIPS_BASE_ADDRESS: 772 return "MIPS_BASE_ADDRESS"; 773 case DT_MIPS_CONFLICT: 774 return "MIPS_CONFLICT"; 775 case DT_MIPS_LIBLIST: 776 return "MIPS_LIBLIST"; 777 case DT_MIPS_LOCAL_GOTNO: 778 return "MIPS_LOCAL_GOTNO"; 779 case DT_MIPS_CONFLICTNO: 780 return "MIPS_CONFLICTNO"; 781 case DT_MIPS_LIBLISTNO: 782 return "MIPS_LIBLISTNO"; 783 case DT_MIPS_SYMTABNO: 784 return "MIPS_SYMTABNO"; 785 case DT_MIPS_UNREFEXTNO: 786 return "MIPS_UNREFEXTNO"; 787 case DT_MIPS_GOTSYM: 788 return "MIPS_GOTSYM"; 789 case DT_MIPS_HIPAGENO: 790 return "MIPS_HIPAGENO"; 791 case DT_MIPS_RLD_MAP: 792 return "MIPS_RLD_MAP"; 793 case DT_MIPS_DELTA_CLASS: 794 return "MIPS_DELTA_CLASS"; 795 case DT_MIPS_DELTA_CLASS_NO: 796 return "MIPS_DELTA_CLASS_NO"; 797 case DT_MIPS_DELTA_INSTANCE: 798 return "MIPS_DELTA_INSTANCE"; 799 case DT_MIPS_DELTA_INSTANCE_NO: 800 return "MIPS_DELTA_INSTANCE_NO"; 801 case DT_MIPS_DELTA_RELOC: 802 return "MIPS_DELTA_RELOC"; 803 case DT_MIPS_DELTA_RELOC_NO: 804 return "MIPS_DELTA_RELOC_NO"; 805 case DT_MIPS_DELTA_SYM: 806 return "MIPS_DELTA_SYM"; 807 case DT_MIPS_DELTA_SYM_NO: 808 return "MIPS_DELTA_SYM_NO"; 809 case DT_MIPS_DELTA_CLASSSYM: 810 return "MIPS_DELTA_CLASSSYM"; 811 case DT_MIPS_DELTA_CLASSSYM_NO: 812 return "MIPS_DELTA_CLASSSYM_NO"; 813 case DT_MIPS_CXX_FLAGS: 814 return "MIPS_CXX_FLAGS"; 815 case DT_MIPS_PIXIE_INIT: 816 return "MIPS_PIXIE_INIT"; 817 case DT_MIPS_SYMBOL_LIB: 818 return "MIPS_SYMBOL_LIB"; 819 case DT_MIPS_LOCALPAGE_GOTIDX: 820 return "MIPS_LOCALPAGE_GOTIDX"; 821 case DT_MIPS_LOCAL_GOTIDX: 822 return "MIPS_LOCAL_GOTIDX"; 823 case DT_MIPS_HIDDEN_GOTIDX: 824 return "MIPS_HIDDEN_GOTIDX"; 825 case DT_MIPS_PROTECTED_GOTIDX: 826 return "MIPS_PROTECTED_GOTIDX"; 827 case DT_MIPS_OPTIONS: 828 return "MIPS_OPTIONS"; 829 case DT_MIPS_INTERFACE: 830 return "MIPS_INTERFACE"; 831 case DT_MIPS_DYNSTR_ALIGN: 832 return "MIPS_DYNSTR_ALIGN"; 833 case DT_MIPS_INTERFACE_SIZE: 834 return "MIPS_INTERFACE_SIZE"; 835 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: 836 return "MIPS_RLD_TEXT_RESOLVE_ADDR"; 837 case DT_MIPS_PERF_SUFFIX: 838 return "MIPS_PERF_SUFFIX"; 839 case DT_MIPS_COMPACT_SIZE: 840 return "MIPS_COMPACT_SIZE"; 841 case DT_MIPS_GP_VALUE: 842 return "MIPS_GP_VALUE"; 843 case DT_MIPS_AUX_DYNAMIC: 844 return "MIPS_AUX_DYNAMIC"; 845 case DT_MIPS_PLTGOT: 846 return "MIPS_PLTGOT"; 847 case DT_MIPS_RLD_OBJ_UPDATE: 848 return "MIPS_RLD_OBJ_UPDATE"; 849 case DT_MIPS_RWPLT: 850 return "MIPS_RWPLT"; 851 default: 852 break; 853 } 854 break; 855 case EM_SPARC: 856 case EM_SPARC32PLUS: 857 case EM_SPARCV9: 858 switch (dtype) { 859 case DT_SPARC_REGISTER: 860 return "DT_SPARC_REGISTER"; 861 default: 862 break; 863 } 864 break; 865 default: 866 break; 867 } 868 snprintf(s_dtype, sizeof(s_dtype), "<unknown: %#x>", dtype); 869 return (s_dtype); 870 } 871 872 switch (dtype) { 873 case DT_NULL: return "NULL"; 874 case DT_NEEDED: return "NEEDED"; 875 case DT_PLTRELSZ: return "PLTRELSZ"; 876 case DT_PLTGOT: return "PLTGOT"; 877 case DT_HASH: return "HASH"; 878 case DT_STRTAB: return "STRTAB"; 879 case DT_SYMTAB: return "SYMTAB"; 880 case DT_RELA: return "RELA"; 881 case DT_RELASZ: return "RELASZ"; 882 case DT_RELAENT: return "RELAENT"; 883 case DT_STRSZ: return "STRSZ"; 884 case DT_SYMENT: return "SYMENT"; 885 case DT_INIT: return "INIT"; 886 case DT_FINI: return "FINI"; 887 case DT_SONAME: return "SONAME"; 888 case DT_RPATH: return "RPATH"; 889 case DT_SYMBOLIC: return "SYMBOLIC"; 890 case DT_REL: return "REL"; 891 case DT_RELSZ: return "RELSZ"; 892 case DT_RELENT: return "RELENT"; 893 case DT_PLTREL: return "PLTREL"; 894 case DT_DEBUG: return "DEBUG"; 895 case DT_TEXTREL: return "TEXTREL"; 896 case DT_JMPREL: return "JMPREL"; 897 case DT_BIND_NOW: return "BIND_NOW"; 898 case DT_INIT_ARRAY: return "INIT_ARRAY"; 899 case DT_FINI_ARRAY: return "FINI_ARRAY"; 900 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ"; 901 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ"; 902 case DT_RUNPATH: return "RUNPATH"; 903 case DT_FLAGS: return "FLAGS"; 904 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY"; 905 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ"; 906 case DT_MAXPOSTAGS: return "MAXPOSTAGS"; 907 case DT_SUNW_AUXILIARY: return "SUNW_AUXILIARY"; 908 case DT_SUNW_RTLDINF: return "SUNW_RTLDINF"; 909 case DT_SUNW_FILTER: return "SUNW_FILTER"; 910 case DT_SUNW_CAP: return "SUNW_CAP"; 911 case DT_CHECKSUM: return "CHECKSUM"; 912 case DT_PLTPADSZ: return "PLTPADSZ"; 913 case DT_MOVEENT: return "MOVEENT"; 914 case DT_MOVESZ: return "MOVESZ"; 915 case DT_FEATURE: return "FEATURE"; 916 case DT_POSFLAG_1: return "POSFLAG_1"; 917 case DT_SYMINSZ: return "SYMINSZ"; 918 case DT_SYMINENT: return "SYMINENT"; 919 case DT_GNU_HASH: return "GNU_HASH"; 920 case DT_GNU_CONFLICT: return "GNU_CONFLICT"; 921 case DT_GNU_LIBLIST: return "GNU_LIBLIST"; 922 case DT_CONFIG: return "CONFIG"; 923 case DT_DEPAUDIT: return "DEPAUDIT"; 924 case DT_AUDIT: return "AUDIT"; 925 case DT_PLTPAD: return "PLTPAD"; 926 case DT_MOVETAB: return "MOVETAB"; 927 case DT_SYMINFO: return "SYMINFO"; 928 case DT_VERSYM: return "VERSYM"; 929 case DT_RELACOUNT: return "RELACOUNT"; 930 case DT_RELCOUNT: return "RELCOUNT"; 931 case DT_FLAGS_1: return "FLAGS_1"; 932 case DT_VERDEF: return "VERDEF"; 933 case DT_VERDEFNUM: return "VERDEFNUM"; 934 case DT_VERNEED: return "VERNEED"; 935 case DT_VERNEEDNUM: return "VERNEEDNUM"; 936 case DT_AUXILIARY: return "AUXILIARY"; 937 case DT_USED: return "USED"; 938 case DT_FILTER: return "FILTER"; 939 case DT_GNU_PRELINKED: return "GNU_PRELINKED"; 940 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ"; 941 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ"; 942 default: 943 snprintf(s_dtype, sizeof(s_dtype), "<unknown: %#x>", dtype); 944 return (s_dtype); 945 } 946 } 947 948 static const char * 949 st_bind(unsigned int sbind) 950 { 951 static char s_sbind[32]; 952 953 switch (sbind) { 954 case STB_LOCAL: return "LOCAL"; 955 case STB_GLOBAL: return "GLOBAL"; 956 case STB_WEAK: return "WEAK"; 957 default: 958 if (sbind >= STB_LOOS && sbind <= STB_HIOS) 959 return "OS"; 960 else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC) 961 return "PROC"; 962 else 963 snprintf(s_sbind, sizeof(s_sbind), "<unknown: %#x>", 964 sbind); 965 return (s_sbind); 966 } 967 } 968 969 static const char * 970 st_type(unsigned int stype) 971 { 972 static char s_stype[32]; 973 974 switch (stype) { 975 case STT_NOTYPE: return "NOTYPE"; 976 case STT_OBJECT: return "OBJECT"; 977 case STT_FUNC: return "FUNC"; 978 case STT_SECTION: return "SECTION"; 979 case STT_FILE: return "FILE"; 980 case STT_COMMON: return "COMMON"; 981 case STT_TLS: return "TLS"; 982 default: 983 if (stype >= STT_LOOS && stype <= STT_HIOS) 984 snprintf(s_stype, sizeof(s_stype), "OS+%#x", 985 stype - STT_LOOS); 986 else if (stype >= STT_LOPROC && stype <= STT_HIPROC) 987 snprintf(s_stype, sizeof(s_stype), "PROC+%#x", 988 stype - STT_LOPROC); 989 else 990 snprintf(s_stype, sizeof(s_stype), "<unknown: %#x>", 991 stype); 992 return (s_stype); 993 } 994 } 995 996 static const char * 997 st_vis(unsigned int svis) 998 { 999 static char s_svis[32]; 1000 1001 switch(svis) { 1002 case STV_DEFAULT: return "DEFAULT"; 1003 case STV_INTERNAL: return "INTERNAL"; 1004 case STV_HIDDEN: return "HIDDEN"; 1005 case STV_PROTECTED: return "PROTECTED"; 1006 default: 1007 snprintf(s_svis, sizeof(s_svis), "<unknown: %#x>", svis); 1008 return (s_svis); 1009 } 1010 } 1011 1012 static const char * 1013 st_shndx(unsigned int shndx) 1014 { 1015 static char s_shndx[32]; 1016 1017 switch (shndx) { 1018 case SHN_UNDEF: return "UND"; 1019 case SHN_ABS: return "ABS"; 1020 case SHN_COMMON: return "COM"; 1021 default: 1022 if (shndx >= SHN_LOPROC && shndx <= SHN_HIPROC) 1023 return "PRC"; 1024 else if (shndx >= SHN_LOOS && shndx <= SHN_HIOS) 1025 return "OS"; 1026 else 1027 snprintf(s_shndx, sizeof(s_shndx), "%u", shndx); 1028 return (s_shndx); 1029 } 1030 } 1031 1032 static struct { 1033 const char *ln; 1034 char sn; 1035 int value; 1036 } section_flag[] = { 1037 {"WRITE", 'W', SHF_WRITE}, 1038 {"ALLOC", 'A', SHF_ALLOC}, 1039 {"EXEC", 'X', SHF_EXECINSTR}, 1040 {"MERGE", 'M', SHF_MERGE}, 1041 {"STRINGS", 'S', SHF_STRINGS}, 1042 {"INFO LINK", 'I', SHF_INFO_LINK}, 1043 {"OS NONCONF", 'O', SHF_OS_NONCONFORMING}, 1044 {"GROUP", 'G', SHF_GROUP}, 1045 {"TLS", 'T', SHF_TLS}, 1046 {NULL, 0, 0} 1047 }; 1048 1049 static const char * 1050 r_type(unsigned int mach, unsigned int type) 1051 { 1052 switch(mach) { 1053 case EM_NONE: return ""; 1054 case EM_386: 1055 case EM_IAMCU: 1056 switch(type) { 1057 case 0: return "R_386_NONE"; 1058 case 1: return "R_386_32"; 1059 case 2: return "R_386_PC32"; 1060 case 3: return "R_386_GOT32"; 1061 case 4: return "R_386_PLT32"; 1062 case 5: return "R_386_COPY"; 1063 case 6: return "R_386_GLOB_DAT"; 1064 case 7: return "R_386_JMP_SLOT"; 1065 case 8: return "R_386_RELATIVE"; 1066 case 9: return "R_386_GOTOFF"; 1067 case 10: return "R_386_GOTPC"; 1068 case 14: return "R_386_TLS_TPOFF"; 1069 case 15: return "R_386_TLS_IE"; 1070 case 16: return "R_386_TLS_GOTIE"; 1071 case 17: return "R_386_TLS_LE"; 1072 case 18: return "R_386_TLS_GD"; 1073 case 19: return "R_386_TLS_LDM"; 1074 case 24: return "R_386_TLS_GD_32"; 1075 case 25: return "R_386_TLS_GD_PUSH"; 1076 case 26: return "R_386_TLS_GD_CALL"; 1077 case 27: return "R_386_TLS_GD_POP"; 1078 case 28: return "R_386_TLS_LDM_32"; 1079 case 29: return "R_386_TLS_LDM_PUSH"; 1080 case 30: return "R_386_TLS_LDM_CALL"; 1081 case 31: return "R_386_TLS_LDM_POP"; 1082 case 32: return "R_386_TLS_LDO_32"; 1083 case 33: return "R_386_TLS_IE_32"; 1084 case 34: return "R_386_TLS_LE_32"; 1085 case 35: return "R_386_TLS_DTPMOD32"; 1086 case 36: return "R_386_TLS_DTPOFF32"; 1087 case 37: return "R_386_TLS_TPOFF32"; 1088 default: return ""; 1089 } 1090 case EM_AARCH64: 1091 switch(type) { 1092 case 0: return "R_AARCH64_NONE"; 1093 case 257: return "R_AARCH64_ABS64"; 1094 case 258: return "R_AARCH64_ABS32"; 1095 case 259: return "R_AARCH64_ABS16"; 1096 case 260: return "R_AARCH64_PREL64"; 1097 case 261: return "R_AARCH64_PREL32"; 1098 case 262: return "R_AARCH64_PREL16"; 1099 case 263: return "R_AARCH64_MOVW_UABS_G0"; 1100 case 264: return "R_AARCH64_MOVW_UABS_G0_NC"; 1101 case 265: return "R_AARCH64_MOVW_UABS_G1"; 1102 case 266: return "R_AARCH64_MOVW_UABS_G1_NC"; 1103 case 267: return "R_AARCH64_MOVW_UABS_G2"; 1104 case 268: return "R_AARCH64_MOVW_UABS_G2_NC"; 1105 case 269: return "R_AARCH64_MOVW_UABS_G3"; 1106 case 270: return "R_AARCH64_MOVW_SABS_G0"; 1107 case 271: return "R_AARCH64_MOVW_SABS_G1"; 1108 case 272: return "R_AARCH64_MOVW_SABS_G2"; 1109 case 273: return "R_AARCH64_LD_PREL_LO19"; 1110 case 274: return "R_AARCH64_ADR_PREL_LO21"; 1111 case 275: return "R_AARCH64_ADR_PREL_PG_HI21"; 1112 case 276: return "R_AARCH64_ADR_PREL_PG_HI21_NC"; 1113 case 277: return "R_AARCH64_ADD_ABS_LO12_NC"; 1114 case 278: return "R_AARCH64_LDST8_ABS_LO12_NC"; 1115 case 279: return "R_AARCH64_TSTBR14"; 1116 case 280: return "R_AARCH64_CONDBR19"; 1117 case 282: return "R_AARCH64_JUMP26"; 1118 case 283: return "R_AARCH64_CALL26"; 1119 case 284: return "R_AARCH64_LDST16_ABS_LO12_NC"; 1120 case 285: return "R_AARCH64_LDST32_ABS_LO12_NC"; 1121 case 286: return "R_AARCH64_LDST64_ABS_LO12_NC"; 1122 case 287: return "R_AARCH64_MOVW_PREL_G0"; 1123 case 288: return "R_AARCH64_MOVW_PREL_G0_NC"; 1124 case 289: return "R_AARCH64_MOVW_PREL_G1"; 1125 case 290: return "R_AARCH64_MOVW_PREL_G1_NC"; 1126 case 291: return "R_AARCH64_MOVW_PREL_G2"; 1127 case 292: return "R_AARCH64_MOVW_PREL_G2_NC"; 1128 case 293: return "R_AARCH64_MOVW_PREL_G3"; 1129 case 299: return "R_AARCH64_LDST128_ABS_LO12_NC"; 1130 case 300: return "R_AARCH64_MOVW_GOTOFF_G0"; 1131 case 301: return "R_AARCH64_MOVW_GOTOFF_G0_NC"; 1132 case 302: return "R_AARCH64_MOVW_GOTOFF_G1"; 1133 case 303: return "R_AARCH64_MOVW_GOTOFF_G1_NC"; 1134 case 304: return "R_AARCH64_MOVW_GOTOFF_G2"; 1135 case 305: return "R_AARCH64_MOVW_GOTOFF_G2_NC"; 1136 case 306: return "R_AARCH64_MOVW_GOTOFF_G3"; 1137 case 307: return "R_AARCH64_GOTREL64"; 1138 case 308: return "R_AARCH64_GOTREL32"; 1139 case 309: return "R_AARCH64_GOT_LD_PREL19"; 1140 case 310: return "R_AARCH64_LD64_GOTOFF_LO15"; 1141 case 311: return "R_AARCH64_ADR_GOT_PAGE"; 1142 case 312: return "R_AARCH64_LD64_GOT_LO12_NC"; 1143 case 313: return "R_AARCH64_LD64_GOTPAGE_LO15"; 1144 case 1024: return "R_AARCH64_COPY"; 1145 case 1025: return "R_AARCH64_GLOB_DAT"; 1146 case 1026: return "R_AARCH64_JUMP_SLOT"; 1147 case 1027: return "R_AARCH64_RELATIVE"; 1148 case 1028: return "R_AARCH64_TLS_DTPREL64"; 1149 case 1029: return "R_AARCH64_TLS_DTPMOD64"; 1150 case 1030: return "R_AARCH64_TLS_TPREL64"; 1151 case 1031: return "R_AARCH64_TLSDESC"; 1152 case 1032: return "R_AARCH64_IRELATIVE"; 1153 default: return ""; 1154 } 1155 case EM_ARM: 1156 switch(type) { 1157 case 0: return "R_ARM_NONE"; 1158 case 1: return "R_ARM_PC24"; 1159 case 2: return "R_ARM_ABS32"; 1160 case 3: return "R_ARM_REL32"; 1161 case 4: return "R_ARM_PC13"; 1162 case 5: return "R_ARM_ABS16"; 1163 case 6: return "R_ARM_ABS12"; 1164 case 7: return "R_ARM_THM_ABS5"; 1165 case 8: return "R_ARM_ABS8"; 1166 case 9: return "R_ARM_SBREL32"; 1167 case 10: return "R_ARM_THM_PC22"; 1168 case 11: return "R_ARM_THM_PC8"; 1169 case 12: return "R_ARM_AMP_VCALL9"; 1170 case 13: return "R_ARM_SWI24"; 1171 case 14: return "R_ARM_THM_SWI8"; 1172 case 15: return "R_ARM_XPC25"; 1173 case 16: return "R_ARM_THM_XPC22"; 1174 case 20: return "R_ARM_COPY"; 1175 case 21: return "R_ARM_GLOB_DAT"; 1176 case 22: return "R_ARM_JUMP_SLOT"; 1177 case 23: return "R_ARM_RELATIVE"; 1178 case 24: return "R_ARM_GOTOFF"; 1179 case 25: return "R_ARM_GOTPC"; 1180 case 26: return "R_ARM_GOT32"; 1181 case 27: return "R_ARM_PLT32"; 1182 case 100: return "R_ARM_GNU_VTENTRY"; 1183 case 101: return "R_ARM_GNU_VTINHERIT"; 1184 case 250: return "R_ARM_RSBREL32"; 1185 case 251: return "R_ARM_THM_RPC22"; 1186 case 252: return "R_ARM_RREL32"; 1187 case 253: return "R_ARM_RABS32"; 1188 case 254: return "R_ARM_RPC24"; 1189 case 255: return "R_ARM_RBASE"; 1190 default: return ""; 1191 } 1192 case EM_IA_64: 1193 switch(type) { 1194 case 0: return "R_IA_64_NONE"; 1195 case 33: return "R_IA_64_IMM14"; 1196 case 34: return "R_IA_64_IMM22"; 1197 case 35: return "R_IA_64_IMM64"; 1198 case 36: return "R_IA_64_DIR32MSB"; 1199 case 37: return "R_IA_64_DIR32LSB"; 1200 case 38: return "R_IA_64_DIR64MSB"; 1201 case 39: return "R_IA_64_DIR64LSB"; 1202 case 42: return "R_IA_64_GPREL22"; 1203 case 43: return "R_IA_64_GPREL64I"; 1204 case 44: return "R_IA_64_GPREL32MSB"; 1205 case 45: return "R_IA_64_GPREL32LSB"; 1206 case 46: return "R_IA_64_GPREL64MSB"; 1207 case 47: return "R_IA_64_GPREL64LSB"; 1208 case 50: return "R_IA_64_LTOFF22"; 1209 case 51: return "R_IA_64_LTOFF64I"; 1210 case 58: return "R_IA_64_PLTOFF22"; 1211 case 59: return "R_IA_64_PLTOFF64I"; 1212 case 62: return "R_IA_64_PLTOFF64MSB"; 1213 case 63: return "R_IA_64_PLTOFF64LSB"; 1214 case 67: return "R_IA_64_FPTR64I"; 1215 case 68: return "R_IA_64_FPTR32MSB"; 1216 case 69: return "R_IA_64_FPTR32LSB"; 1217 case 70: return "R_IA_64_FPTR64MSB"; 1218 case 71: return "R_IA_64_FPTR64LSB"; 1219 case 72: return "R_IA_64_PCREL60B"; 1220 case 73: return "R_IA_64_PCREL21B"; 1221 case 74: return "R_IA_64_PCREL21M"; 1222 case 75: return "R_IA_64_PCREL21F"; 1223 case 76: return "R_IA_64_PCREL32MSB"; 1224 case 77: return "R_IA_64_PCREL32LSB"; 1225 case 78: return "R_IA_64_PCREL64MSB"; 1226 case 79: return "R_IA_64_PCREL64LSB"; 1227 case 82: return "R_IA_64_LTOFF_FPTR22"; 1228 case 83: return "R_IA_64_LTOFF_FPTR64I"; 1229 case 84: return "R_IA_64_LTOFF_FPTR32MSB"; 1230 case 85: return "R_IA_64_LTOFF_FPTR32LSB"; 1231 case 86: return "R_IA_64_LTOFF_FPTR64MSB"; 1232 case 87: return "R_IA_64_LTOFF_FPTR64LSB"; 1233 case 92: return "R_IA_64_SEGREL32MSB"; 1234 case 93: return "R_IA_64_SEGREL32LSB"; 1235 case 94: return "R_IA_64_SEGREL64MSB"; 1236 case 95: return "R_IA_64_SEGREL64LSB"; 1237 case 100: return "R_IA_64_SECREL32MSB"; 1238 case 101: return "R_IA_64_SECREL32LSB"; 1239 case 102: return "R_IA_64_SECREL64MSB"; 1240 case 103: return "R_IA_64_SECREL64LSB"; 1241 case 108: return "R_IA_64_REL32MSB"; 1242 case 109: return "R_IA_64_REL32LSB"; 1243 case 110: return "R_IA_64_REL64MSB"; 1244 case 111: return "R_IA_64_REL64LSB"; 1245 case 116: return "R_IA_64_LTV32MSB"; 1246 case 117: return "R_IA_64_LTV32LSB"; 1247 case 118: return "R_IA_64_LTV64MSB"; 1248 case 119: return "R_IA_64_LTV64LSB"; 1249 case 121: return "R_IA_64_PCREL21BI"; 1250 case 122: return "R_IA_64_PCREL22"; 1251 case 123: return "R_IA_64_PCREL64I"; 1252 case 128: return "R_IA_64_IPLTMSB"; 1253 case 129: return "R_IA_64_IPLTLSB"; 1254 case 133: return "R_IA_64_SUB"; 1255 case 134: return "R_IA_64_LTOFF22X"; 1256 case 135: return "R_IA_64_LDXMOV"; 1257 case 145: return "R_IA_64_TPREL14"; 1258 case 146: return "R_IA_64_TPREL22"; 1259 case 147: return "R_IA_64_TPREL64I"; 1260 case 150: return "R_IA_64_TPREL64MSB"; 1261 case 151: return "R_IA_64_TPREL64LSB"; 1262 case 154: return "R_IA_64_LTOFF_TPREL22"; 1263 case 166: return "R_IA_64_DTPMOD64MSB"; 1264 case 167: return "R_IA_64_DTPMOD64LSB"; 1265 case 170: return "R_IA_64_LTOFF_DTPMOD22"; 1266 case 177: return "R_IA_64_DTPREL14"; 1267 case 178: return "R_IA_64_DTPREL22"; 1268 case 179: return "R_IA_64_DTPREL64I"; 1269 case 180: return "R_IA_64_DTPREL32MSB"; 1270 case 181: return "R_IA_64_DTPREL32LSB"; 1271 case 182: return "R_IA_64_DTPREL64MSB"; 1272 case 183: return "R_IA_64_DTPREL64LSB"; 1273 case 186: return "R_IA_64_LTOFF_DTPREL22"; 1274 default: return ""; 1275 } 1276 case EM_MIPS: 1277 switch(type) { 1278 case 0: return "R_MIPS_NONE"; 1279 case 1: return "R_MIPS_16"; 1280 case 2: return "R_MIPS_32"; 1281 case 3: return "R_MIPS_REL32"; 1282 case 4: return "R_MIPS_26"; 1283 case 5: return "R_MIPS_HI16"; 1284 case 6: return "R_MIPS_LO16"; 1285 case 7: return "R_MIPS_GPREL16"; 1286 case 8: return "R_MIPS_LITERAL"; 1287 case 9: return "R_MIPS_GOT16"; 1288 case 10: return "R_MIPS_PC16"; 1289 case 11: return "R_MIPS_CALL16"; 1290 case 12: return "R_MIPS_GPREL32"; 1291 case 21: return "R_MIPS_GOTHI16"; 1292 case 22: return "R_MIPS_GOTLO16"; 1293 case 30: return "R_MIPS_CALLHI16"; 1294 case 31: return "R_MIPS_CALLLO16"; 1295 default: return ""; 1296 } 1297 case EM_PPC: 1298 switch(type) { 1299 case 0: return "R_PPC_NONE"; 1300 case 1: return "R_PPC_ADDR32"; 1301 case 2: return "R_PPC_ADDR24"; 1302 case 3: return "R_PPC_ADDR16"; 1303 case 4: return "R_PPC_ADDR16_LO"; 1304 case 5: return "R_PPC_ADDR16_HI"; 1305 case 6: return "R_PPC_ADDR16_HA"; 1306 case 7: return "R_PPC_ADDR14"; 1307 case 8: return "R_PPC_ADDR14_BRTAKEN"; 1308 case 9: return "R_PPC_ADDR14_BRNTAKEN"; 1309 case 10: return "R_PPC_REL24"; 1310 case 11: return "R_PPC_REL14"; 1311 case 12: return "R_PPC_REL14_BRTAKEN"; 1312 case 13: return "R_PPC_REL14_BRNTAKEN"; 1313 case 14: return "R_PPC_GOT16"; 1314 case 15: return "R_PPC_GOT16_LO"; 1315 case 16: return "R_PPC_GOT16_HI"; 1316 case 17: return "R_PPC_GOT16_HA"; 1317 case 18: return "R_PPC_PLTREL24"; 1318 case 19: return "R_PPC_COPY"; 1319 case 20: return "R_PPC_GLOB_DAT"; 1320 case 21: return "R_PPC_JMP_SLOT"; 1321 case 22: return "R_PPC_RELATIVE"; 1322 case 23: return "R_PPC_LOCAL24PC"; 1323 case 24: return "R_PPC_UADDR32"; 1324 case 25: return "R_PPC_UADDR16"; 1325 case 26: return "R_PPC_REL32"; 1326 case 27: return "R_PPC_PLT32"; 1327 case 28: return "R_PPC_PLTREL32"; 1328 case 29: return "R_PPC_PLT16_LO"; 1329 case 30: return "R_PPC_PLT16_HI"; 1330 case 31: return "R_PPC_PLT16_HA"; 1331 case 32: return "R_PPC_SDAREL16"; 1332 case 33: return "R_PPC_SECTOFF"; 1333 case 34: return "R_PPC_SECTOFF_LO"; 1334 case 35: return "R_PPC_SECTOFF_HI"; 1335 case 36: return "R_PPC_SECTOFF_HA"; 1336 case 67: return "R_PPC_TLS"; 1337 case 68: return "R_PPC_DTPMOD32"; 1338 case 69: return "R_PPC_TPREL16"; 1339 case 70: return "R_PPC_TPREL16_LO"; 1340 case 71: return "R_PPC_TPREL16_HI"; 1341 case 72: return "R_PPC_TPREL16_HA"; 1342 case 73: return "R_PPC_TPREL32"; 1343 case 74: return "R_PPC_DTPREL16"; 1344 case 75: return "R_PPC_DTPREL16_LO"; 1345 case 76: return "R_PPC_DTPREL16_HI"; 1346 case 77: return "R_PPC_DTPREL16_HA"; 1347 case 78: return "R_PPC_DTPREL32"; 1348 case 79: return "R_PPC_GOT_TLSGD16"; 1349 case 80: return "R_PPC_GOT_TLSGD16_LO"; 1350 case 81: return "R_PPC_GOT_TLSGD16_HI"; 1351 case 82: return "R_PPC_GOT_TLSGD16_HA"; 1352 case 83: return "R_PPC_GOT_TLSLD16"; 1353 case 84: return "R_PPC_GOT_TLSLD16_LO"; 1354 case 85: return "R_PPC_GOT_TLSLD16_HI"; 1355 case 86: return "R_PPC_GOT_TLSLD16_HA"; 1356 case 87: return "R_PPC_GOT_TPREL16"; 1357 case 88: return "R_PPC_GOT_TPREL16_LO"; 1358 case 89: return "R_PPC_GOT_TPREL16_HI"; 1359 case 90: return "R_PPC_GOT_TPREL16_HA"; 1360 case 101: return "R_PPC_EMB_NADDR32"; 1361 case 102: return "R_PPC_EMB_NADDR16"; 1362 case 103: return "R_PPC_EMB_NADDR16_LO"; 1363 case 104: return "R_PPC_EMB_NADDR16_HI"; 1364 case 105: return "R_PPC_EMB_NADDR16_HA"; 1365 case 106: return "R_PPC_EMB_SDAI16"; 1366 case 107: return "R_PPC_EMB_SDA2I16"; 1367 case 108: return "R_PPC_EMB_SDA2REL"; 1368 case 109: return "R_PPC_EMB_SDA21"; 1369 case 110: return "R_PPC_EMB_MRKREF"; 1370 case 111: return "R_PPC_EMB_RELSEC16"; 1371 case 112: return "R_PPC_EMB_RELST_LO"; 1372 case 113: return "R_PPC_EMB_RELST_HI"; 1373 case 114: return "R_PPC_EMB_RELST_HA"; 1374 case 115: return "R_PPC_EMB_BIT_FLD"; 1375 case 116: return "R_PPC_EMB_RELSDA"; 1376 default: return ""; 1377 } 1378 case EM_SPARC: 1379 case EM_SPARCV9: 1380 switch(type) { 1381 case 0: return "R_SPARC_NONE"; 1382 case 1: return "R_SPARC_8"; 1383 case 2: return "R_SPARC_16"; 1384 case 3: return "R_SPARC_32"; 1385 case 4: return "R_SPARC_DISP8"; 1386 case 5: return "R_SPARC_DISP16"; 1387 case 6: return "R_SPARC_DISP32"; 1388 case 7: return "R_SPARC_WDISP30"; 1389 case 8: return "R_SPARC_WDISP22"; 1390 case 9: return "R_SPARC_HI22"; 1391 case 10: return "R_SPARC_22"; 1392 case 11: return "R_SPARC_13"; 1393 case 12: return "R_SPARC_LO10"; 1394 case 13: return "R_SPARC_GOT10"; 1395 case 14: return "R_SPARC_GOT13"; 1396 case 15: return "R_SPARC_GOT22"; 1397 case 16: return "R_SPARC_PC10"; 1398 case 17: return "R_SPARC_PC22"; 1399 case 18: return "R_SPARC_WPLT30"; 1400 case 19: return "R_SPARC_COPY"; 1401 case 20: return "R_SPARC_GLOB_DAT"; 1402 case 21: return "R_SPARC_JMP_SLOT"; 1403 case 22: return "R_SPARC_RELATIVE"; 1404 case 23: return "R_SPARC_UA32"; 1405 case 24: return "R_SPARC_PLT32"; 1406 case 25: return "R_SPARC_HIPLT22"; 1407 case 26: return "R_SPARC_LOPLT10"; 1408 case 27: return "R_SPARC_PCPLT32"; 1409 case 28: return "R_SPARC_PCPLT22"; 1410 case 29: return "R_SPARC_PCPLT10"; 1411 case 30: return "R_SPARC_10"; 1412 case 31: return "R_SPARC_11"; 1413 case 32: return "R_SPARC_64"; 1414 case 33: return "R_SPARC_OLO10"; 1415 case 34: return "R_SPARC_HH22"; 1416 case 35: return "R_SPARC_HM10"; 1417 case 36: return "R_SPARC_LM22"; 1418 case 37: return "R_SPARC_PC_HH22"; 1419 case 38: return "R_SPARC_PC_HM10"; 1420 case 39: return "R_SPARC_PC_LM22"; 1421 case 40: return "R_SPARC_WDISP16"; 1422 case 41: return "R_SPARC_WDISP19"; 1423 case 42: return "R_SPARC_GLOB_JMP"; 1424 case 43: return "R_SPARC_7"; 1425 case 44: return "R_SPARC_5"; 1426 case 45: return "R_SPARC_6"; 1427 case 46: return "R_SPARC_DISP64"; 1428 case 47: return "R_SPARC_PLT64"; 1429 case 48: return "R_SPARC_HIX22"; 1430 case 49: return "R_SPARC_LOX10"; 1431 case 50: return "R_SPARC_H44"; 1432 case 51: return "R_SPARC_M44"; 1433 case 52: return "R_SPARC_L44"; 1434 case 53: return "R_SPARC_REGISTER"; 1435 case 54: return "R_SPARC_UA64"; 1436 case 55: return "R_SPARC_UA16"; 1437 case 56: return "R_SPARC_TLS_GD_HI22"; 1438 case 57: return "R_SPARC_TLS_GD_LO10"; 1439 case 58: return "R_SPARC_TLS_GD_ADD"; 1440 case 59: return "R_SPARC_TLS_GD_CALL"; 1441 case 60: return "R_SPARC_TLS_LDM_HI22"; 1442 case 61: return "R_SPARC_TLS_LDM_LO10"; 1443 case 62: return "R_SPARC_TLS_LDM_ADD"; 1444 case 63: return "R_SPARC_TLS_LDM_CALL"; 1445 case 64: return "R_SPARC_TLS_LDO_HIX22"; 1446 case 65: return "R_SPARC_TLS_LDO_LOX10"; 1447 case 66: return "R_SPARC_TLS_LDO_ADD"; 1448 case 67: return "R_SPARC_TLS_IE_HI22"; 1449 case 68: return "R_SPARC_TLS_IE_LO10"; 1450 case 69: return "R_SPARC_TLS_IE_LD"; 1451 case 70: return "R_SPARC_TLS_IE_LDX"; 1452 case 71: return "R_SPARC_TLS_IE_ADD"; 1453 case 72: return "R_SPARC_TLS_LE_HIX22"; 1454 case 73: return "R_SPARC_TLS_LE_LOX10"; 1455 case 74: return "R_SPARC_TLS_DTPMOD32"; 1456 case 75: return "R_SPARC_TLS_DTPMOD64"; 1457 case 76: return "R_SPARC_TLS_DTPOFF32"; 1458 case 77: return "R_SPARC_TLS_DTPOFF64"; 1459 case 78: return "R_SPARC_TLS_TPOFF32"; 1460 case 79: return "R_SPARC_TLS_TPOFF64"; 1461 default: return ""; 1462 } 1463 case EM_X86_64: 1464 switch(type) { 1465 case 0: return "R_X86_64_NONE"; 1466 case 1: return "R_X86_64_64"; 1467 case 2: return "R_X86_64_PC32"; 1468 case 3: return "R_X86_64_GOT32"; 1469 case 4: return "R_X86_64_PLT32"; 1470 case 5: return "R_X86_64_COPY"; 1471 case 6: return "R_X86_64_GLOB_DAT"; 1472 case 7: return "R_X86_64_JMP_SLOT"; 1473 case 8: return "R_X86_64_RELATIVE"; 1474 case 9: return "R_X86_64_GOTPCREL"; 1475 case 10: return "R_X86_64_32"; 1476 case 11: return "R_X86_64_32S"; 1477 case 12: return "R_X86_64_16"; 1478 case 13: return "R_X86_64_PC16"; 1479 case 14: return "R_X86_64_8"; 1480 case 15: return "R_X86_64_PC8"; 1481 case 16: return "R_X86_64_DTPMOD64"; 1482 case 17: return "R_X86_64_DTPOFF64"; 1483 case 18: return "R_X86_64_TPOFF64"; 1484 case 19: return "R_X86_64_TLSGD"; 1485 case 20: return "R_X86_64_TLSLD"; 1486 case 21: return "R_X86_64_DTPOFF32"; 1487 case 22: return "R_X86_64_GOTTPOFF"; 1488 case 23: return "R_X86_64_TPOFF32"; 1489 case 24: return "R_X86_64_PC64"; 1490 case 25: return "R_X86_64_GOTOFF64"; 1491 case 26: return "R_X86_64_GOTPC32"; 1492 case 27: return "R_X86_64_GOT64"; 1493 case 28: return "R_X86_64_GOTPCREL64"; 1494 case 29: return "R_X86_64_GOTPC64"; 1495 case 30: return "R_X86_64_GOTPLT64"; 1496 case 31: return "R_X86_64_PLTOFF64"; 1497 case 32: return "R_X86_64_SIZE32"; 1498 case 33: return "R_X86_64_SIZE64"; 1499 case 34: return "R_X86_64_GOTPC32_TLSDESC"; 1500 case 35: return "R_X86_64_TLSDESC_CALL"; 1501 case 36: return "R_X86_64_TLSDESC"; 1502 case 37: return "R_X86_64_IRELATIVE"; 1503 default: return ""; 1504 } 1505 default: return ""; 1506 } 1507 } 1508 1509 static const char * 1510 note_type(const char *name, unsigned int et, unsigned int nt) 1511 { 1512 if ((strcmp(name, "CORE") == 0 || strcmp(name, "LINUX") == 0) && 1513 et == ET_CORE) 1514 return note_type_linux_core(nt); 1515 else if (strcmp(name, "FreeBSD") == 0) 1516 if (et == ET_CORE) 1517 return note_type_freebsd_core(nt); 1518 else 1519 return note_type_freebsd(nt); 1520 else if (strcmp(name, "GNU") == 0 && et != ET_CORE) 1521 return note_type_gnu(nt); 1522 else if (strcmp(name, "NetBSD") == 0 && et != ET_CORE) 1523 return note_type_netbsd(nt); 1524 else if (strcmp(name, "OpenBSD") == 0 && et != ET_CORE) 1525 return note_type_openbsd(nt); 1526 return note_type_unknown(nt); 1527 } 1528 1529 static const char * 1530 note_type_freebsd(unsigned int nt) 1531 { 1532 switch (nt) { 1533 case 1: return "NT_FREEBSD_ABI_TAG"; 1534 case 2: return "NT_FREEBSD_NOINIT_TAG"; 1535 case 3: return "NT_FREEBSD_ARCH_TAG"; 1536 default: return (note_type_unknown(nt)); 1537 } 1538 } 1539 1540 static const char * 1541 note_type_freebsd_core(unsigned int nt) 1542 { 1543 switch (nt) { 1544 case 1: return "NT_PRSTATUS"; 1545 case 2: return "NT_FPREGSET"; 1546 case 3: return "NT_PRPSINFO"; 1547 case 7: return "NT_THRMISC"; 1548 case 8: return "NT_PROCSTAT_PROC"; 1549 case 9: return "NT_PROCSTAT_FILES"; 1550 case 10: return "NT_PROCSTAT_VMMAP"; 1551 case 11: return "NT_PROCSTAT_GROUPS"; 1552 case 12: return "NT_PROCSTAT_UMASK"; 1553 case 13: return "NT_PROCSTAT_RLIMIT"; 1554 case 14: return "NT_PROCSTAT_OSREL"; 1555 case 15: return "NT_PROCSTAT_PSSTRINGS"; 1556 case 16: return "NT_PROCSTAT_AUXV"; 1557 case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)"; 1558 default: return (note_type_unknown(nt)); 1559 } 1560 } 1561 1562 static const char * 1563 note_type_linux_core(unsigned int nt) 1564 { 1565 switch (nt) { 1566 case 1: return "NT_PRSTATUS (Process status)"; 1567 case 2: return "NT_FPREGSET (Floating point information)"; 1568 case 3: return "NT_PRPSINFO (Process information)"; 1569 case 4: return "NT_TASKSTRUCT (Task structure)"; 1570 case 6: return "NT_AUXV (Auxiliary vector)"; 1571 case 10: return "NT_PSTATUS (Linux process status)"; 1572 case 12: return "NT_FPREGS (Linux floating point regset)"; 1573 case 13: return "NT_PSINFO (Linux process information)"; 1574 case 16: return "NT_LWPSTATUS (Linux lwpstatus_t type)"; 1575 case 17: return "NT_LWPSINFO (Linux lwpinfo_t type)"; 1576 case 18: return "NT_WIN32PSTATUS (win32_pstatus structure)"; 1577 case 0x100: return "NT_PPC_VMX (ppc Altivec registers)"; 1578 case 0x102: return "NT_PPC_VSX (ppc VSX registers)"; 1579 case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)"; 1580 case 0x300: return "NT_S390_HIGH_GPRS (s390 upper register halves)"; 1581 case 0x301: return "NT_S390_TIMER (s390 timer register)"; 1582 case 0x302: return "NT_S390_TODCMP (s390 TOD comparator register)"; 1583 case 0x303: return "NT_S390_TODPREG (s390 TOD programmable register)"; 1584 case 0x304: return "NT_S390_CTRS (s390 control registers)"; 1585 case 0x305: return "NT_S390_PREFIX (s390 prefix register)"; 1586 case 0x400: return "NT_ARM_VFP (arm VFP registers)"; 1587 case 0x46494c45UL: return "NT_FILE (mapped files)"; 1588 case 0x46E62B7FUL: return "NT_PRXFPREG (Linux user_xfpregs structure)"; 1589 case 0x53494749UL: return "NT_SIGINFO (siginfo_t data)"; 1590 default: return (note_type_unknown(nt)); 1591 } 1592 } 1593 1594 static const char * 1595 note_type_gnu(unsigned int nt) 1596 { 1597 switch (nt) { 1598 case 1: return "NT_GNU_ABI_TAG"; 1599 case 2: return "NT_GNU_HWCAP (Hardware capabilities)"; 1600 case 3: return "NT_GNU_BUILD_ID (Build id set by ld(1))"; 1601 case 4: return "NT_GNU_GOLD_VERSION (GNU gold version)"; 1602 default: return (note_type_unknown(nt)); 1603 } 1604 } 1605 1606 static const char * 1607 note_type_netbsd(unsigned int nt) 1608 { 1609 switch (nt) { 1610 case 1: return "NT_NETBSD_IDENT"; 1611 default: return (note_type_unknown(nt)); 1612 } 1613 } 1614 1615 static const char * 1616 note_type_openbsd(unsigned int nt) 1617 { 1618 switch (nt) { 1619 case 1: return "NT_OPENBSD_IDENT"; 1620 default: return (note_type_unknown(nt)); 1621 } 1622 } 1623 1624 static const char * 1625 note_type_unknown(unsigned int nt) 1626 { 1627 static char s_nt[32]; 1628 1629 snprintf(s_nt, sizeof(s_nt), 1630 nt >= 0x100 ? "<unknown: 0x%x>" : "<unknown: %u>", nt); 1631 return (s_nt); 1632 } 1633 1634 static struct { 1635 const char *name; 1636 int value; 1637 } l_flag[] = { 1638 {"EXACT_MATCH", LL_EXACT_MATCH}, 1639 {"IGNORE_INT_VER", LL_IGNORE_INT_VER}, 1640 {"REQUIRE_MINOR", LL_REQUIRE_MINOR}, 1641 {"EXPORTS", LL_EXPORTS}, 1642 {"DELAY_LOAD", LL_DELAY_LOAD}, 1643 {"DELTA", LL_DELTA}, 1644 {NULL, 0} 1645 }; 1646 1647 static struct mips_option mips_exceptions_option[] = { 1648 {OEX_PAGE0, "PAGE0"}, 1649 {OEX_SMM, "SMM"}, 1650 {OEX_PRECISEFP, "PRECISEFP"}, 1651 {OEX_DISMISS, "DISMISS"}, 1652 {0, NULL} 1653 }; 1654 1655 static struct mips_option mips_pad_option[] = { 1656 {OPAD_PREFIX, "PREFIX"}, 1657 {OPAD_POSTFIX, "POSTFIX"}, 1658 {OPAD_SYMBOL, "SYMBOL"}, 1659 {0, NULL} 1660 }; 1661 1662 static struct mips_option mips_hwpatch_option[] = { 1663 {OHW_R4KEOP, "R4KEOP"}, 1664 {OHW_R8KPFETCH, "R8KPFETCH"}, 1665 {OHW_R5KEOP, "R5KEOP"}, 1666 {OHW_R5KCVTL, "R5KCVTL"}, 1667 {0, NULL} 1668 }; 1669 1670 static struct mips_option mips_hwa_option[] = { 1671 {OHWA0_R4KEOP_CHECKED, "R4KEOP_CHECKED"}, 1672 {OHWA0_R4KEOP_CLEAN, "R4KEOP_CLEAN"}, 1673 {0, NULL} 1674 }; 1675 1676 static struct mips_option mips_hwo_option[] = { 1677 {OHWO0_FIXADE, "FIXADE"}, 1678 {0, NULL} 1679 }; 1680 1681 static const char * 1682 option_kind(uint8_t kind) 1683 { 1684 static char s_kind[32]; 1685 1686 switch (kind) { 1687 case ODK_NULL: return "NULL"; 1688 case ODK_REGINFO: return "REGINFO"; 1689 case ODK_EXCEPTIONS: return "EXCEPTIONS"; 1690 case ODK_PAD: return "PAD"; 1691 case ODK_HWPATCH: return "HWPATCH"; 1692 case ODK_FILL: return "FILL"; 1693 case ODK_TAGS: return "TAGS"; 1694 case ODK_HWAND: return "HWAND"; 1695 case ODK_HWOR: return "HWOR"; 1696 case ODK_GP_GROUP: return "GP_GROUP"; 1697 case ODK_IDENT: return "IDENT"; 1698 default: 1699 snprintf(s_kind, sizeof(s_kind), "<unknown: %u>", kind); 1700 return (s_kind); 1701 } 1702 } 1703 1704 static const char * 1705 top_tag(unsigned int tag) 1706 { 1707 static char s_top_tag[32]; 1708 1709 switch (tag) { 1710 case 1: return "File Attributes"; 1711 case 2: return "Section Attributes"; 1712 case 3: return "Symbol Attributes"; 1713 default: 1714 snprintf(s_top_tag, sizeof(s_top_tag), "Unknown tag: %u", tag); 1715 return (s_top_tag); 1716 } 1717 } 1718 1719 static const char * 1720 aeabi_cpu_arch(uint64_t arch) 1721 { 1722 static char s_cpu_arch[32]; 1723 1724 switch (arch) { 1725 case 0: return "Pre-V4"; 1726 case 1: return "ARM v4"; 1727 case 2: return "ARM v4T"; 1728 case 3: return "ARM v5T"; 1729 case 4: return "ARM v5TE"; 1730 case 5: return "ARM v5TEJ"; 1731 case 6: return "ARM v6"; 1732 case 7: return "ARM v6KZ"; 1733 case 8: return "ARM v6T2"; 1734 case 9: return "ARM v6K"; 1735 case 10: return "ARM v7"; 1736 case 11: return "ARM v6-M"; 1737 case 12: return "ARM v6S-M"; 1738 case 13: return "ARM v7E-M"; 1739 default: 1740 snprintf(s_cpu_arch, sizeof(s_cpu_arch), 1741 "Unknown (%ju)", (uintmax_t) arch); 1742 return (s_cpu_arch); 1743 } 1744 } 1745 1746 static const char * 1747 aeabi_cpu_arch_profile(uint64_t pf) 1748 { 1749 static char s_arch_profile[32]; 1750 1751 switch (pf) { 1752 case 0: 1753 return "Not applicable"; 1754 case 0x41: /* 'A' */ 1755 return "Application Profile"; 1756 case 0x52: /* 'R' */ 1757 return "Real-Time Profile"; 1758 case 0x4D: /* 'M' */ 1759 return "Microcontroller Profile"; 1760 case 0x53: /* 'S' */ 1761 return "Application or Real-Time Profile"; 1762 default: 1763 snprintf(s_arch_profile, sizeof(s_arch_profile), 1764 "Unknown (%ju)\n", (uintmax_t) pf); 1765 return (s_arch_profile); 1766 } 1767 } 1768 1769 static const char * 1770 aeabi_arm_isa(uint64_t ai) 1771 { 1772 static char s_ai[32]; 1773 1774 switch (ai) { 1775 case 0: return "No"; 1776 case 1: return "Yes"; 1777 default: 1778 snprintf(s_ai, sizeof(s_ai), "Unknown (%ju)\n", 1779 (uintmax_t) ai); 1780 return (s_ai); 1781 } 1782 } 1783 1784 static const char * 1785 aeabi_thumb_isa(uint64_t ti) 1786 { 1787 static char s_ti[32]; 1788 1789 switch (ti) { 1790 case 0: return "No"; 1791 case 1: return "16-bit Thumb"; 1792 case 2: return "32-bit Thumb"; 1793 default: 1794 snprintf(s_ti, sizeof(s_ti), "Unknown (%ju)\n", 1795 (uintmax_t) ti); 1796 return (s_ti); 1797 } 1798 } 1799 1800 static const char * 1801 aeabi_fp_arch(uint64_t fp) 1802 { 1803 static char s_fp_arch[32]; 1804 1805 switch (fp) { 1806 case 0: return "No"; 1807 case 1: return "VFPv1"; 1808 case 2: return "VFPv2"; 1809 case 3: return "VFPv3"; 1810 case 4: return "VFPv3-D16"; 1811 case 5: return "VFPv4"; 1812 case 6: return "VFPv4-D16"; 1813 default: 1814 snprintf(s_fp_arch, sizeof(s_fp_arch), "Unknown (%ju)", 1815 (uintmax_t) fp); 1816 return (s_fp_arch); 1817 } 1818 } 1819 1820 static const char * 1821 aeabi_wmmx_arch(uint64_t wmmx) 1822 { 1823 static char s_wmmx[32]; 1824 1825 switch (wmmx) { 1826 case 0: return "No"; 1827 case 1: return "WMMXv1"; 1828 case 2: return "WMMXv2"; 1829 default: 1830 snprintf(s_wmmx, sizeof(s_wmmx), "Unknown (%ju)", 1831 (uintmax_t) wmmx); 1832 return (s_wmmx); 1833 } 1834 } 1835 1836 static const char * 1837 aeabi_adv_simd_arch(uint64_t simd) 1838 { 1839 static char s_simd[32]; 1840 1841 switch (simd) { 1842 case 0: return "No"; 1843 case 1: return "NEONv1"; 1844 case 2: return "NEONv2"; 1845 default: 1846 snprintf(s_simd, sizeof(s_simd), "Unknown (%ju)", 1847 (uintmax_t) simd); 1848 return (s_simd); 1849 } 1850 } 1851 1852 static const char * 1853 aeabi_pcs_config(uint64_t pcs) 1854 { 1855 static char s_pcs[32]; 1856 1857 switch (pcs) { 1858 case 0: return "None"; 1859 case 1: return "Bare platform"; 1860 case 2: return "Linux"; 1861 case 3: return "Linux DSO"; 1862 case 4: return "Palm OS 2004"; 1863 case 5: return "Palm OS (future)"; 1864 case 6: return "Symbian OS 2004"; 1865 case 7: return "Symbian OS (future)"; 1866 default: 1867 snprintf(s_pcs, sizeof(s_pcs), "Unknown (%ju)", 1868 (uintmax_t) pcs); 1869 return (s_pcs); 1870 } 1871 } 1872 1873 static const char * 1874 aeabi_pcs_r9(uint64_t r9) 1875 { 1876 static char s_r9[32]; 1877 1878 switch (r9) { 1879 case 0: return "V6"; 1880 case 1: return "SB"; 1881 case 2: return "TLS pointer"; 1882 case 3: return "Unused"; 1883 default: 1884 snprintf(s_r9, sizeof(s_r9), "Unknown (%ju)", (uintmax_t) r9); 1885 return (s_r9); 1886 } 1887 } 1888 1889 static const char * 1890 aeabi_pcs_rw(uint64_t rw) 1891 { 1892 static char s_rw[32]; 1893 1894 switch (rw) { 1895 case 0: return "Absolute"; 1896 case 1: return "PC-relative"; 1897 case 2: return "SB-relative"; 1898 case 3: return "None"; 1899 default: 1900 snprintf(s_rw, sizeof(s_rw), "Unknown (%ju)", (uintmax_t) rw); 1901 return (s_rw); 1902 } 1903 } 1904 1905 static const char * 1906 aeabi_pcs_ro(uint64_t ro) 1907 { 1908 static char s_ro[32]; 1909 1910 switch (ro) { 1911 case 0: return "Absolute"; 1912 case 1: return "PC-relative"; 1913 case 2: return "None"; 1914 default: 1915 snprintf(s_ro, sizeof(s_ro), "Unknown (%ju)", (uintmax_t) ro); 1916 return (s_ro); 1917 } 1918 } 1919 1920 static const char * 1921 aeabi_pcs_got(uint64_t got) 1922 { 1923 static char s_got[32]; 1924 1925 switch (got) { 1926 case 0: return "None"; 1927 case 1: return "direct"; 1928 case 2: return "indirect via GOT"; 1929 default: 1930 snprintf(s_got, sizeof(s_got), "Unknown (%ju)", 1931 (uintmax_t) got); 1932 return (s_got); 1933 } 1934 } 1935 1936 static const char * 1937 aeabi_pcs_wchar_t(uint64_t wt) 1938 { 1939 static char s_wt[32]; 1940 1941 switch (wt) { 1942 case 0: return "None"; 1943 case 2: return "wchar_t size 2"; 1944 case 4: return "wchar_t size 4"; 1945 default: 1946 snprintf(s_wt, sizeof(s_wt), "Unknown (%ju)", (uintmax_t) wt); 1947 return (s_wt); 1948 } 1949 } 1950 1951 static const char * 1952 aeabi_enum_size(uint64_t es) 1953 { 1954 static char s_es[32]; 1955 1956 switch (es) { 1957 case 0: return "None"; 1958 case 1: return "smallest"; 1959 case 2: return "32-bit"; 1960 case 3: return "visible 32-bit"; 1961 default: 1962 snprintf(s_es, sizeof(s_es), "Unknown (%ju)", (uintmax_t) es); 1963 return (s_es); 1964 } 1965 } 1966 1967 static const char * 1968 aeabi_align_needed(uint64_t an) 1969 { 1970 static char s_align_n[64]; 1971 1972 switch (an) { 1973 case 0: return "No"; 1974 case 1: return "8-byte align"; 1975 case 2: return "4-byte align"; 1976 case 3: return "Reserved"; 1977 default: 1978 if (an >= 4 && an <= 12) 1979 snprintf(s_align_n, sizeof(s_align_n), "8-byte align" 1980 " and up to 2^%ju-byte extended align", 1981 (uintmax_t) an); 1982 else 1983 snprintf(s_align_n, sizeof(s_align_n), "Unknown (%ju)", 1984 (uintmax_t) an); 1985 return (s_align_n); 1986 } 1987 } 1988 1989 static const char * 1990 aeabi_align_preserved(uint64_t ap) 1991 { 1992 static char s_align_p[128]; 1993 1994 switch (ap) { 1995 case 0: return "No"; 1996 case 1: return "8-byte align"; 1997 case 2: return "8-byte align and SP % 8 == 0"; 1998 case 3: return "Reserved"; 1999 default: 2000 if (ap >= 4 && ap <= 12) 2001 snprintf(s_align_p, sizeof(s_align_p), "8-byte align" 2002 " and SP %% 8 == 0 and up to 2^%ju-byte extended" 2003 " align", (uintmax_t) ap); 2004 else 2005 snprintf(s_align_p, sizeof(s_align_p), "Unknown (%ju)", 2006 (uintmax_t) ap); 2007 return (s_align_p); 2008 } 2009 } 2010 2011 static const char * 2012 aeabi_fp_rounding(uint64_t fr) 2013 { 2014 static char s_fp_r[32]; 2015 2016 switch (fr) { 2017 case 0: return "Unused"; 2018 case 1: return "Needed"; 2019 default: 2020 snprintf(s_fp_r, sizeof(s_fp_r), "Unknown (%ju)", 2021 (uintmax_t) fr); 2022 return (s_fp_r); 2023 } 2024 } 2025 2026 static const char * 2027 aeabi_fp_denormal(uint64_t fd) 2028 { 2029 static char s_fp_d[32]; 2030 2031 switch (fd) { 2032 case 0: return "Unused"; 2033 case 1: return "Needed"; 2034 case 2: return "Sign Only"; 2035 default: 2036 snprintf(s_fp_d, sizeof(s_fp_d), "Unknown (%ju)", 2037 (uintmax_t) fd); 2038 return (s_fp_d); 2039 } 2040 } 2041 2042 static const char * 2043 aeabi_fp_exceptions(uint64_t fe) 2044 { 2045 static char s_fp_e[32]; 2046 2047 switch (fe) { 2048 case 0: return "Unused"; 2049 case 1: return "Needed"; 2050 default: 2051 snprintf(s_fp_e, sizeof(s_fp_e), "Unknown (%ju)", 2052 (uintmax_t) fe); 2053 return (s_fp_e); 2054 } 2055 } 2056 2057 static const char * 2058 aeabi_fp_user_exceptions(uint64_t fu) 2059 { 2060 static char s_fp_u[32]; 2061 2062 switch (fu) { 2063 case 0: return "Unused"; 2064 case 1: return "Needed"; 2065 default: 2066 snprintf(s_fp_u, sizeof(s_fp_u), "Unknown (%ju)", 2067 (uintmax_t) fu); 2068 return (s_fp_u); 2069 } 2070 } 2071 2072 static const char * 2073 aeabi_fp_number_model(uint64_t fn) 2074 { 2075 static char s_fp_n[32]; 2076 2077 switch (fn) { 2078 case 0: return "Unused"; 2079 case 1: return "IEEE 754 normal"; 2080 case 2: return "RTABI"; 2081 case 3: return "IEEE 754"; 2082 default: 2083 snprintf(s_fp_n, sizeof(s_fp_n), "Unknown (%ju)", 2084 (uintmax_t) fn); 2085 return (s_fp_n); 2086 } 2087 } 2088 2089 static const char * 2090 aeabi_fp_16bit_format(uint64_t fp16) 2091 { 2092 static char s_fp_16[64]; 2093 2094 switch (fp16) { 2095 case 0: return "None"; 2096 case 1: return "IEEE 754"; 2097 case 2: return "VFPv3/Advanced SIMD (alternative format)"; 2098 default: 2099 snprintf(s_fp_16, sizeof(s_fp_16), "Unknown (%ju)", 2100 (uintmax_t) fp16); 2101 return (s_fp_16); 2102 } 2103 } 2104 2105 static const char * 2106 aeabi_mpext(uint64_t mp) 2107 { 2108 static char s_mp[32]; 2109 2110 switch (mp) { 2111 case 0: return "Not allowed"; 2112 case 1: return "Allowed"; 2113 default: 2114 snprintf(s_mp, sizeof(s_mp), "Unknown (%ju)", 2115 (uintmax_t) mp); 2116 return (s_mp); 2117 } 2118 } 2119 2120 static const char * 2121 aeabi_div(uint64_t du) 2122 { 2123 static char s_du[32]; 2124 2125 switch (du) { 2126 case 0: return "Yes (V7-R/V7-M)"; 2127 case 1: return "No"; 2128 case 2: return "Yes (V7-A)"; 2129 default: 2130 snprintf(s_du, sizeof(s_du), "Unknown (%ju)", 2131 (uintmax_t) du); 2132 return (s_du); 2133 } 2134 } 2135 2136 static const char * 2137 aeabi_t2ee(uint64_t t2ee) 2138 { 2139 static char s_t2ee[32]; 2140 2141 switch (t2ee) { 2142 case 0: return "Not allowed"; 2143 case 1: return "Allowed"; 2144 default: 2145 snprintf(s_t2ee, sizeof(s_t2ee), "Unknown(%ju)", 2146 (uintmax_t) t2ee); 2147 return (s_t2ee); 2148 } 2149 2150 } 2151 2152 static const char * 2153 aeabi_hardfp(uint64_t hfp) 2154 { 2155 static char s_hfp[32]; 2156 2157 switch (hfp) { 2158 case 0: return "Tag_FP_arch"; 2159 case 1: return "only SP"; 2160 case 2: return "only DP"; 2161 case 3: return "both SP and DP"; 2162 default: 2163 snprintf(s_hfp, sizeof(s_hfp), "Unknown (%ju)", 2164 (uintmax_t) hfp); 2165 return (s_hfp); 2166 } 2167 } 2168 2169 static const char * 2170 aeabi_vfp_args(uint64_t va) 2171 { 2172 static char s_va[32]; 2173 2174 switch (va) { 2175 case 0: return "AAPCS (base variant)"; 2176 case 1: return "AAPCS (VFP variant)"; 2177 case 2: return "toolchain-specific"; 2178 default: 2179 snprintf(s_va, sizeof(s_va), "Unknown (%ju)", (uintmax_t) va); 2180 return (s_va); 2181 } 2182 } 2183 2184 static const char * 2185 aeabi_wmmx_args(uint64_t wa) 2186 { 2187 static char s_wa[32]; 2188 2189 switch (wa) { 2190 case 0: return "AAPCS (base variant)"; 2191 case 1: return "Intel WMMX"; 2192 case 2: return "toolchain-specific"; 2193 default: 2194 snprintf(s_wa, sizeof(s_wa), "Unknown(%ju)", (uintmax_t) wa); 2195 return (s_wa); 2196 } 2197 } 2198 2199 static const char * 2200 aeabi_unaligned_access(uint64_t ua) 2201 { 2202 static char s_ua[32]; 2203 2204 switch (ua) { 2205 case 0: return "Not allowed"; 2206 case 1: return "Allowed"; 2207 default: 2208 snprintf(s_ua, sizeof(s_ua), "Unknown(%ju)", (uintmax_t) ua); 2209 return (s_ua); 2210 } 2211 } 2212 2213 static const char * 2214 aeabi_fp_hpext(uint64_t fh) 2215 { 2216 static char s_fh[32]; 2217 2218 switch (fh) { 2219 case 0: return "Not allowed"; 2220 case 1: return "Allowed"; 2221 default: 2222 snprintf(s_fh, sizeof(s_fh), "Unknown(%ju)", (uintmax_t) fh); 2223 return (s_fh); 2224 } 2225 } 2226 2227 static const char * 2228 aeabi_optm_goal(uint64_t og) 2229 { 2230 static char s_og[32]; 2231 2232 switch (og) { 2233 case 0: return "None"; 2234 case 1: return "Speed"; 2235 case 2: return "Speed aggressive"; 2236 case 3: return "Space"; 2237 case 4: return "Space aggressive"; 2238 case 5: return "Debugging"; 2239 case 6: return "Best Debugging"; 2240 default: 2241 snprintf(s_og, sizeof(s_og), "Unknown(%ju)", (uintmax_t) og); 2242 return (s_og); 2243 } 2244 } 2245 2246 static const char * 2247 aeabi_fp_optm_goal(uint64_t fog) 2248 { 2249 static char s_fog[32]; 2250 2251 switch (fog) { 2252 case 0: return "None"; 2253 case 1: return "Speed"; 2254 case 2: return "Speed aggressive"; 2255 case 3: return "Space"; 2256 case 4: return "Space aggressive"; 2257 case 5: return "Accurary"; 2258 case 6: return "Best Accurary"; 2259 default: 2260 snprintf(s_fog, sizeof(s_fog), "Unknown(%ju)", 2261 (uintmax_t) fog); 2262 return (s_fog); 2263 } 2264 } 2265 2266 static const char * 2267 aeabi_virtual(uint64_t vt) 2268 { 2269 static char s_virtual[64]; 2270 2271 switch (vt) { 2272 case 0: return "No"; 2273 case 1: return "TrustZone"; 2274 case 2: return "Virtualization extension"; 2275 case 3: return "TrustZone and virtualization extension"; 2276 default: 2277 snprintf(s_virtual, sizeof(s_virtual), "Unknown(%ju)", 2278 (uintmax_t) vt); 2279 return (s_virtual); 2280 } 2281 } 2282 2283 static struct { 2284 uint64_t tag; 2285 const char *s_tag; 2286 const char *(*get_desc)(uint64_t val); 2287 } aeabi_tags[] = { 2288 {4, "Tag_CPU_raw_name", NULL}, 2289 {5, "Tag_CPU_name", NULL}, 2290 {6, "Tag_CPU_arch", aeabi_cpu_arch}, 2291 {7, "Tag_CPU_arch_profile", aeabi_cpu_arch_profile}, 2292 {8, "Tag_ARM_ISA_use", aeabi_arm_isa}, 2293 {9, "Tag_THUMB_ISA_use", aeabi_thumb_isa}, 2294 {10, "Tag_FP_arch", aeabi_fp_arch}, 2295 {11, "Tag_WMMX_arch", aeabi_wmmx_arch}, 2296 {12, "Tag_Advanced_SIMD_arch", aeabi_adv_simd_arch}, 2297 {13, "Tag_PCS_config", aeabi_pcs_config}, 2298 {14, "Tag_ABI_PCS_R9_use", aeabi_pcs_r9}, 2299 {15, "Tag_ABI_PCS_RW_data", aeabi_pcs_rw}, 2300 {16, "Tag_ABI_PCS_RO_data", aeabi_pcs_ro}, 2301 {17, "Tag_ABI_PCS_GOT_use", aeabi_pcs_got}, 2302 {18, "Tag_ABI_PCS_wchar_t", aeabi_pcs_wchar_t}, 2303 {19, "Tag_ABI_FP_rounding", aeabi_fp_rounding}, 2304 {20, "Tag_ABI_FP_denormal", aeabi_fp_denormal}, 2305 {21, "Tag_ABI_FP_exceptions", aeabi_fp_exceptions}, 2306 {22, "Tag_ABI_FP_user_exceptions", aeabi_fp_user_exceptions}, 2307 {23, "Tag_ABI_FP_number_model", aeabi_fp_number_model}, 2308 {24, "Tag_ABI_align_needed", aeabi_align_needed}, 2309 {25, "Tag_ABI_align_preserved", aeabi_align_preserved}, 2310 {26, "Tag_ABI_enum_size", aeabi_enum_size}, 2311 {27, "Tag_ABI_HardFP_use", aeabi_hardfp}, 2312 {28, "Tag_ABI_VFP_args", aeabi_vfp_args}, 2313 {29, "Tag_ABI_WMMX_args", aeabi_wmmx_args}, 2314 {30, "Tag_ABI_optimization_goals", aeabi_optm_goal}, 2315 {31, "Tag_ABI_FP_optimization_goals", aeabi_fp_optm_goal}, 2316 {32, "Tag_compatibility", NULL}, 2317 {34, "Tag_CPU_unaligned_access", aeabi_unaligned_access}, 2318 {36, "Tag_FP_HP_extension", aeabi_fp_hpext}, 2319 {38, "Tag_ABI_FP_16bit_format", aeabi_fp_16bit_format}, 2320 {42, "Tag_MPextension_use", aeabi_mpext}, 2321 {44, "Tag_DIV_use", aeabi_div}, 2322 {64, "Tag_nodefaults", NULL}, 2323 {65, "Tag_also_compatible_with", NULL}, 2324 {66, "Tag_T2EE_use", aeabi_t2ee}, 2325 {67, "Tag_conformance", NULL}, 2326 {68, "Tag_Virtualization_use", aeabi_virtual}, 2327 {70, "Tag_MPextension_use", aeabi_mpext}, 2328 }; 2329 2330 static const char * 2331 mips_abi_fp(uint64_t fp) 2332 { 2333 static char s_mips_abi_fp[64]; 2334 2335 switch (fp) { 2336 case 0: return "N/A"; 2337 case 1: return "Hard float (double precision)"; 2338 case 2: return "Hard float (single precision)"; 2339 case 3: return "Soft float"; 2340 case 4: return "64-bit float (-mips32r2 -mfp64)"; 2341 default: 2342 snprintf(s_mips_abi_fp, sizeof(s_mips_abi_fp), "Unknown(%ju)", 2343 (uintmax_t) fp); 2344 return (s_mips_abi_fp); 2345 } 2346 } 2347 2348 static const char * 2349 ppc_abi_fp(uint64_t fp) 2350 { 2351 static char s_ppc_abi_fp[64]; 2352 2353 switch (fp) { 2354 case 0: return "N/A"; 2355 case 1: return "Hard float (double precision)"; 2356 case 2: return "Soft float"; 2357 case 3: return "Hard float (single precision)"; 2358 default: 2359 snprintf(s_ppc_abi_fp, sizeof(s_ppc_abi_fp), "Unknown(%ju)", 2360 (uintmax_t) fp); 2361 return (s_ppc_abi_fp); 2362 } 2363 } 2364 2365 static const char * 2366 ppc_abi_vector(uint64_t vec) 2367 { 2368 static char s_vec[64]; 2369 2370 switch (vec) { 2371 case 0: return "N/A"; 2372 case 1: return "Generic purpose registers"; 2373 case 2: return "AltiVec registers"; 2374 case 3: return "SPE registers"; 2375 default: 2376 snprintf(s_vec, sizeof(s_vec), "Unknown(%ju)", (uintmax_t) vec); 2377 return (s_vec); 2378 } 2379 } 2380 2381 static const char * 2382 dwarf_reg(unsigned int mach, unsigned int reg) 2383 { 2384 2385 switch (mach) { 2386 case EM_386: 2387 case EM_IAMCU: 2388 switch (reg) { 2389 case 0: return "eax"; 2390 case 1: return "ecx"; 2391 case 2: return "edx"; 2392 case 3: return "ebx"; 2393 case 4: return "esp"; 2394 case 5: return "ebp"; 2395 case 6: return "esi"; 2396 case 7: return "edi"; 2397 case 8: return "eip"; 2398 case 9: return "eflags"; 2399 case 11: return "st0"; 2400 case 12: return "st1"; 2401 case 13: return "st2"; 2402 case 14: return "st3"; 2403 case 15: return "st4"; 2404 case 16: return "st5"; 2405 case 17: return "st6"; 2406 case 18: return "st7"; 2407 case 21: return "xmm0"; 2408 case 22: return "xmm1"; 2409 case 23: return "xmm2"; 2410 case 24: return "xmm3"; 2411 case 25: return "xmm4"; 2412 case 26: return "xmm5"; 2413 case 27: return "xmm6"; 2414 case 28: return "xmm7"; 2415 case 29: return "mm0"; 2416 case 30: return "mm1"; 2417 case 31: return "mm2"; 2418 case 32: return "mm3"; 2419 case 33: return "mm4"; 2420 case 34: return "mm5"; 2421 case 35: return "mm6"; 2422 case 36: return "mm7"; 2423 case 37: return "fcw"; 2424 case 38: return "fsw"; 2425 case 39: return "mxcsr"; 2426 case 40: return "es"; 2427 case 41: return "cs"; 2428 case 42: return "ss"; 2429 case 43: return "ds"; 2430 case 44: return "fs"; 2431 case 45: return "gs"; 2432 case 48: return "tr"; 2433 case 49: return "ldtr"; 2434 default: return (NULL); 2435 } 2436 case EM_X86_64: 2437 switch (reg) { 2438 case 0: return "rax"; 2439 case 1: return "rdx"; 2440 case 2: return "rcx"; 2441 case 3: return "rbx"; 2442 case 4: return "rsi"; 2443 case 5: return "rdi"; 2444 case 6: return "rbp"; 2445 case 7: return "rsp"; 2446 case 16: return "rip"; 2447 case 17: return "xmm0"; 2448 case 18: return "xmm1"; 2449 case 19: return "xmm2"; 2450 case 20: return "xmm3"; 2451 case 21: return "xmm4"; 2452 case 22: return "xmm5"; 2453 case 23: return "xmm6"; 2454 case 24: return "xmm7"; 2455 case 25: return "xmm8"; 2456 case 26: return "xmm9"; 2457 case 27: return "xmm10"; 2458 case 28: return "xmm11"; 2459 case 29: return "xmm12"; 2460 case 30: return "xmm13"; 2461 case 31: return "xmm14"; 2462 case 32: return "xmm15"; 2463 case 33: return "st0"; 2464 case 34: return "st1"; 2465 case 35: return "st2"; 2466 case 36: return "st3"; 2467 case 37: return "st4"; 2468 case 38: return "st5"; 2469 case 39: return "st6"; 2470 case 40: return "st7"; 2471 case 41: return "mm0"; 2472 case 42: return "mm1"; 2473 case 43: return "mm2"; 2474 case 44: return "mm3"; 2475 case 45: return "mm4"; 2476 case 46: return "mm5"; 2477 case 47: return "mm6"; 2478 case 48: return "mm7"; 2479 case 49: return "rflags"; 2480 case 50: return "es"; 2481 case 51: return "cs"; 2482 case 52: return "ss"; 2483 case 53: return "ds"; 2484 case 54: return "fs"; 2485 case 55: return "gs"; 2486 case 58: return "fs.base"; 2487 case 59: return "gs.base"; 2488 case 62: return "tr"; 2489 case 63: return "ldtr"; 2490 case 64: return "mxcsr"; 2491 case 65: return "fcw"; 2492 case 66: return "fsw"; 2493 default: return (NULL); 2494 } 2495 default: 2496 return (NULL); 2497 } 2498 } 2499 2500 static void 2501 dump_ehdr(struct readelf *re) 2502 { 2503 size_t shnum, shstrndx; 2504 int i; 2505 2506 printf("ELF Header:\n"); 2507 2508 /* e_ident[]. */ 2509 printf(" Magic: "); 2510 for (i = 0; i < EI_NIDENT; i++) 2511 printf("%.2x ", re->ehdr.e_ident[i]); 2512 putchar('\n'); 2513 2514 /* EI_CLASS. */ 2515 printf("%-37s%s\n", " Class:", elf_class(re->ehdr.e_ident[EI_CLASS])); 2516 2517 /* EI_DATA. */ 2518 printf("%-37s%s\n", " Data:", elf_endian(re->ehdr.e_ident[EI_DATA])); 2519 2520 /* EI_VERSION. */ 2521 printf("%-37s%d %s\n", " Version:", re->ehdr.e_ident[EI_VERSION], 2522 elf_ver(re->ehdr.e_ident[EI_VERSION])); 2523 2524 /* EI_OSABI. */ 2525 printf("%-37s%s\n", " OS/ABI:", elf_osabi(re->ehdr.e_ident[EI_OSABI])); 2526 2527 /* EI_ABIVERSION. */ 2528 printf("%-37s%d\n", " ABI Version:", re->ehdr.e_ident[EI_ABIVERSION]); 2529 2530 /* e_type. */ 2531 printf("%-37s%s\n", " Type:", elf_type(re->ehdr.e_type)); 2532 2533 /* e_machine. */ 2534 printf("%-37s%s\n", " Machine:", elf_machine(re->ehdr.e_machine)); 2535 2536 /* e_version. */ 2537 printf("%-37s%#x\n", " Version:", re->ehdr.e_version); 2538 2539 /* e_entry. */ 2540 printf("%-37s%#jx\n", " Entry point address:", 2541 (uintmax_t)re->ehdr.e_entry); 2542 2543 /* e_phoff. */ 2544 printf("%-37s%ju (bytes into file)\n", " Start of program headers:", 2545 (uintmax_t)re->ehdr.e_phoff); 2546 2547 /* e_shoff. */ 2548 printf("%-37s%ju (bytes into file)\n", " Start of section headers:", 2549 (uintmax_t)re->ehdr.e_shoff); 2550 2551 /* e_flags. */ 2552 printf("%-37s%#x", " Flags:", re->ehdr.e_flags); 2553 dump_eflags(re, re->ehdr.e_flags); 2554 putchar('\n'); 2555 2556 /* e_ehsize. */ 2557 printf("%-37s%u (bytes)\n", " Size of this header:", 2558 re->ehdr.e_ehsize); 2559 2560 /* e_phentsize. */ 2561 printf("%-37s%u (bytes)\n", " Size of program headers:", 2562 re->ehdr.e_phentsize); 2563 2564 /* e_phnum. */ 2565 printf("%-37s%u\n", " Number of program headers:", re->ehdr.e_phnum); 2566 2567 /* e_shentsize. */ 2568 printf("%-37s%u (bytes)\n", " Size of section headers:", 2569 re->ehdr.e_shentsize); 2570 2571 /* e_shnum. */ 2572 printf("%-37s%u", " Number of section headers:", re->ehdr.e_shnum); 2573 if (re->ehdr.e_shnum == SHN_UNDEF) { 2574 /* Extended section numbering is in use. */ 2575 if (elf_getshnum(re->elf, &shnum)) 2576 printf(" (%ju)", (uintmax_t)shnum); 2577 } 2578 putchar('\n'); 2579 2580 /* e_shstrndx. */ 2581 printf("%-37s%u", " Section header string table index:", 2582 re->ehdr.e_shstrndx); 2583 if (re->ehdr.e_shstrndx == SHN_XINDEX) { 2584 /* Extended section numbering is in use. */ 2585 if (elf_getshstrndx(re->elf, &shstrndx)) 2586 printf(" (%ju)", (uintmax_t)shstrndx); 2587 } 2588 putchar('\n'); 2589 } 2590 2591 static void 2592 dump_eflags(struct readelf *re, uint64_t e_flags) 2593 { 2594 struct eflags_desc *edesc; 2595 int arm_eabi; 2596 2597 edesc = NULL; 2598 switch (re->ehdr.e_machine) { 2599 case EM_ARM: 2600 arm_eabi = (e_flags & EF_ARM_EABIMASK) >> 24; 2601 if (arm_eabi == 0) 2602 printf(", GNU EABI"); 2603 else if (arm_eabi <= 5) 2604 printf(", Version%d EABI", arm_eabi); 2605 edesc = arm_eflags_desc; 2606 break; 2607 case EM_MIPS: 2608 case EM_MIPS_RS3_LE: 2609 switch ((e_flags & EF_MIPS_ARCH) >> 28) { 2610 case 0: printf(", mips1"); break; 2611 case 1: printf(", mips2"); break; 2612 case 2: printf(", mips3"); break; 2613 case 3: printf(", mips4"); break; 2614 case 4: printf(", mips5"); break; 2615 case 5: printf(", mips32"); break; 2616 case 6: printf(", mips64"); break; 2617 case 7: printf(", mips32r2"); break; 2618 case 8: printf(", mips64r2"); break; 2619 default: break; 2620 } 2621 switch ((e_flags & 0x00FF0000) >> 16) { 2622 case 0x81: printf(", 3900"); break; 2623 case 0x82: printf(", 4010"); break; 2624 case 0x83: printf(", 4100"); break; 2625 case 0x85: printf(", 4650"); break; 2626 case 0x87: printf(", 4120"); break; 2627 case 0x88: printf(", 4111"); break; 2628 case 0x8a: printf(", sb1"); break; 2629 case 0x8b: printf(", octeon"); break; 2630 case 0x8c: printf(", xlr"); break; 2631 case 0x91: printf(", 5400"); break; 2632 case 0x98: printf(", 5500"); break; 2633 case 0x99: printf(", 9000"); break; 2634 case 0xa0: printf(", loongson-2e"); break; 2635 case 0xa1: printf(", loongson-2f"); break; 2636 default: break; 2637 } 2638 switch ((e_flags & 0x0000F000) >> 12) { 2639 case 1: printf(", o32"); break; 2640 case 2: printf(", o64"); break; 2641 case 3: printf(", eabi32"); break; 2642 case 4: printf(", eabi64"); break; 2643 default: break; 2644 } 2645 edesc = mips_eflags_desc; 2646 break; 2647 case EM_PPC: 2648 case EM_PPC64: 2649 edesc = powerpc_eflags_desc; 2650 break; 2651 case EM_SPARC: 2652 case EM_SPARC32PLUS: 2653 case EM_SPARCV9: 2654 switch ((e_flags & EF_SPARCV9_MM)) { 2655 case EF_SPARCV9_TSO: printf(", tso"); break; 2656 case EF_SPARCV9_PSO: printf(", pso"); break; 2657 case EF_SPARCV9_MM: printf(", rmo"); break; 2658 default: break; 2659 } 2660 edesc = sparc_eflags_desc; 2661 break; 2662 default: 2663 break; 2664 } 2665 2666 if (edesc != NULL) { 2667 while (edesc->desc != NULL) { 2668 if (e_flags & edesc->flag) 2669 printf(", %s", edesc->desc); 2670 edesc++; 2671 } 2672 } 2673 } 2674 2675 static void 2676 dump_phdr(struct readelf *re) 2677 { 2678 const char *rawfile; 2679 GElf_Phdr phdr; 2680 size_t phnum, size; 2681 int i, j; 2682 2683 #define PH_HDR "Type", "Offset", "VirtAddr", "PhysAddr", "FileSiz", \ 2684 "MemSiz", "Flg", "Align" 2685 #define PH_CT phdr_type(phdr.p_type), (uintmax_t)phdr.p_offset, \ 2686 (uintmax_t)phdr.p_vaddr, (uintmax_t)phdr.p_paddr, \ 2687 (uintmax_t)phdr.p_filesz, (uintmax_t)phdr.p_memsz, \ 2688 phdr.p_flags & PF_R ? 'R' : ' ', \ 2689 phdr.p_flags & PF_W ? 'W' : ' ', \ 2690 phdr.p_flags & PF_X ? 'E' : ' ', \ 2691 (uintmax_t)phdr.p_align 2692 2693 if (elf_getphnum(re->elf, &phnum) == 0) { 2694 warnx("elf_getphnum failed: %s", elf_errmsg(-1)); 2695 return; 2696 } 2697 if (phnum == 0) { 2698 printf("\nThere are no program headers in this file.\n"); 2699 return; 2700 } 2701 2702 printf("\nElf file type is %s", elf_type(re->ehdr.e_type)); 2703 printf("\nEntry point 0x%jx\n", (uintmax_t)re->ehdr.e_entry); 2704 printf("There are %ju program headers, starting at offset %ju\n", 2705 (uintmax_t)phnum, (uintmax_t)re->ehdr.e_phoff); 2706 2707 /* Dump program headers. */ 2708 printf("\nProgram Headers:\n"); 2709 if (re->ec == ELFCLASS32) 2710 printf(" %-15s%-9s%-11s%-11s%-8s%-8s%-4s%s\n", PH_HDR); 2711 else if (re->options & RE_WW) 2712 printf(" %-15s%-9s%-19s%-19s%-9s%-9s%-4s%s\n", PH_HDR); 2713 else 2714 printf(" %-15s%-19s%-19s%s\n %-19s%-20s" 2715 "%-7s%s\n", PH_HDR); 2716 for (i = 0; (size_t) i < phnum; i++) { 2717 if (gelf_getphdr(re->elf, i, &phdr) != &phdr) { 2718 warnx("gelf_getphdr failed: %s", elf_errmsg(-1)); 2719 continue; 2720 } 2721 /* TODO: Add arch-specific segment type dump. */ 2722 if (re->ec == ELFCLASS32) 2723 printf(" %-14.14s 0x%6.6jx 0x%8.8jx 0x%8.8jx " 2724 "0x%5.5jx 0x%5.5jx %c%c%c %#jx\n", PH_CT); 2725 else if (re->options & RE_WW) 2726 printf(" %-14.14s 0x%6.6jx 0x%16.16jx 0x%16.16jx " 2727 "0x%6.6jx 0x%6.6jx %c%c%c %#jx\n", PH_CT); 2728 else 2729 printf(" %-14.14s 0x%16.16jx 0x%16.16jx 0x%16.16jx\n" 2730 " 0x%16.16jx 0x%16.16jx %c%c%c" 2731 " %#jx\n", PH_CT); 2732 if (phdr.p_type == PT_INTERP) { 2733 if ((rawfile = elf_rawfile(re->elf, &size)) == NULL) { 2734 warnx("elf_rawfile failed: %s", elf_errmsg(-1)); 2735 continue; 2736 } 2737 if (phdr.p_offset >= size) { 2738 warnx("invalid program header offset"); 2739 continue; 2740 } 2741 printf(" [Requesting program interpreter: %s]\n", 2742 rawfile + phdr.p_offset); 2743 } 2744 } 2745 2746 /* Dump section to segment mapping. */ 2747 if (re->shnum == 0) 2748 return; 2749 printf("\n Section to Segment mapping:\n"); 2750 printf(" Segment Sections...\n"); 2751 for (i = 0; (size_t)i < phnum; i++) { 2752 if (gelf_getphdr(re->elf, i, &phdr) != &phdr) { 2753 warnx("gelf_getphdr failed: %s", elf_errmsg(-1)); 2754 continue; 2755 } 2756 printf(" %2.2d ", i); 2757 /* skip NULL section. */ 2758 for (j = 1; (size_t)j < re->shnum; j++) 2759 if (re->sl[j].off >= phdr.p_offset && 2760 re->sl[j].off + re->sl[j].sz <= 2761 phdr.p_offset + phdr.p_memsz) 2762 printf("%s ", re->sl[j].name); 2763 printf("\n"); 2764 } 2765 #undef PH_HDR 2766 #undef PH_CT 2767 } 2768 2769 static char * 2770 section_flags(struct readelf *re, struct section *s) 2771 { 2772 #define BUF_SZ 256 2773 static char buf[BUF_SZ]; 2774 int i, p, nb; 2775 2776 p = 0; 2777 nb = re->ec == ELFCLASS32 ? 8 : 16; 2778 if (re->options & RE_T) { 2779 snprintf(buf, BUF_SZ, "[%*.*jx]: ", nb, nb, 2780 (uintmax_t)s->flags); 2781 p += nb + 4; 2782 } 2783 for (i = 0; section_flag[i].ln != NULL; i++) { 2784 if ((s->flags & section_flag[i].value) == 0) 2785 continue; 2786 if (re->options & RE_T) { 2787 snprintf(&buf[p], BUF_SZ - p, "%s, ", 2788 section_flag[i].ln); 2789 p += strlen(section_flag[i].ln) + 2; 2790 } else 2791 buf[p++] = section_flag[i].sn; 2792 } 2793 if (re->options & RE_T && p > nb + 4) 2794 p -= 2; 2795 buf[p] = '\0'; 2796 2797 return (buf); 2798 } 2799 2800 static void 2801 dump_shdr(struct readelf *re) 2802 { 2803 struct section *s; 2804 int i; 2805 2806 #define S_HDR "[Nr] Name", "Type", "Addr", "Off", "Size", "ES", \ 2807 "Flg", "Lk", "Inf", "Al" 2808 #define S_HDRL "[Nr] Name", "Type", "Address", "Offset", "Size", \ 2809 "EntSize", "Flags", "Link", "Info", "Align" 2810 #define ST_HDR "[Nr] Name", "Type", "Addr", "Off", "Size", "ES", \ 2811 "Lk", "Inf", "Al", "Flags" 2812 #define ST_HDRL "[Nr] Name", "Type", "Address", "Offset", "Link", \ 2813 "Size", "EntSize", "Info", "Align", "Flags" 2814 #define S_CT i, s->name, section_type(re->ehdr.e_machine, s->type), \ 2815 (uintmax_t)s->addr, (uintmax_t)s->off, (uintmax_t)s->sz,\ 2816 (uintmax_t)s->entsize, section_flags(re, s), \ 2817 s->link, s->info, (uintmax_t)s->align 2818 #define ST_CT i, s->name, section_type(re->ehdr.e_machine, s->type), \ 2819 (uintmax_t)s->addr, (uintmax_t)s->off, (uintmax_t)s->sz,\ 2820 (uintmax_t)s->entsize, s->link, s->info, \ 2821 (uintmax_t)s->align, section_flags(re, s) 2822 #define ST_CTL i, s->name, section_type(re->ehdr.e_machine, s->type), \ 2823 (uintmax_t)s->addr, (uintmax_t)s->off, s->link, \ 2824 (uintmax_t)s->sz, (uintmax_t)s->entsize, s->info, \ 2825 (uintmax_t)s->align, section_flags(re, s) 2826 2827 if (re->shnum == 0) { 2828 printf("\nThere are no sections in this file.\n"); 2829 return; 2830 } 2831 printf("There are %ju section headers, starting at offset 0x%jx:\n", 2832 (uintmax_t)re->shnum, (uintmax_t)re->ehdr.e_shoff); 2833 printf("\nSection Headers:\n"); 2834 if (re->ec == ELFCLASS32) { 2835 if (re->options & RE_T) 2836 printf(" %s\n %-16s%-9s%-7s%-7s%-5s%-3s%-4s%s\n" 2837 "%12s\n", ST_HDR); 2838 else 2839 printf(" %-23s%-16s%-9s%-7s%-7s%-3s%-4s%-3s%-4s%s\n", 2840 S_HDR); 2841 } else if (re->options & RE_WW) { 2842 if (re->options & RE_T) 2843 printf(" %s\n %-16s%-17s%-7s%-7s%-5s%-3s%-4s%s\n" 2844 "%12s\n", ST_HDR); 2845 else 2846 printf(" %-23s%-16s%-17s%-7s%-7s%-3s%-4s%-3s%-4s%s\n", 2847 S_HDR); 2848 } else { 2849 if (re->options & RE_T) 2850 printf(" %s\n %-18s%-17s%-18s%s\n %-18s" 2851 "%-17s%-18s%s\n%12s\n", ST_HDRL); 2852 else 2853 printf(" %-23s%-17s%-18s%s\n %-18s%-17s%-7s%" 2854 "-6s%-6s%s\n", S_HDRL); 2855 } 2856 for (i = 0; (size_t)i < re->shnum; i++) { 2857 s = &re->sl[i]; 2858 if (re->ec == ELFCLASS32) { 2859 if (re->options & RE_T) 2860 printf(" [%2d] %s\n %-15.15s %8.8jx" 2861 " %6.6jx %6.6jx %2.2jx %2u %3u %2ju\n" 2862 " %s\n", ST_CT); 2863 else 2864 printf(" [%2d] %-17.17s %-15.15s %8.8jx" 2865 " %6.6jx %6.6jx %2.2jx %3s %2u %3u %2ju\n", 2866 S_CT); 2867 } else if (re->options & RE_WW) { 2868 if (re->options & RE_T) 2869 printf(" [%2d] %s\n %-15.15s %16.16jx" 2870 " %6.6jx %6.6jx %2.2jx %2u %3u %2ju\n" 2871 " %s\n", ST_CT); 2872 else 2873 printf(" [%2d] %-17.17s %-15.15s %16.16jx" 2874 " %6.6jx %6.6jx %2.2jx %3s %2u %3u %2ju\n", 2875 S_CT); 2876 } else { 2877 if (re->options & RE_T) 2878 printf(" [%2d] %s\n %-15.15s %16.16jx" 2879 " %16.16jx %u\n %16.16jx %16.16jx" 2880 " %-16u %ju\n %s\n", ST_CTL); 2881 else 2882 printf(" [%2d] %-17.17s %-15.15s %16.16jx" 2883 " %8.8jx\n %16.16jx %16.16jx " 2884 "%3s %2u %3u %ju\n", S_CT); 2885 } 2886 } 2887 if ((re->options & RE_T) == 0) 2888 printf("Key to Flags:\n W (write), A (alloc)," 2889 " X (execute), M (merge), S (strings)\n" 2890 " I (info), L (link order), G (group), x (unknown)\n" 2891 " O (extra OS processing required)" 2892 " o (OS specific), p (processor specific)\n"); 2893 2894 #undef S_HDR 2895 #undef S_HDRL 2896 #undef ST_HDR 2897 #undef ST_HDRL 2898 #undef S_CT 2899 #undef ST_CT 2900 #undef ST_CTL 2901 } 2902 2903 static void 2904 dump_dynamic(struct readelf *re) 2905 { 2906 GElf_Dyn dyn; 2907 Elf_Data *d; 2908 struct section *s; 2909 int elferr, i, is_dynamic, j, jmax, nentries; 2910 2911 is_dynamic = 0; 2912 2913 for (i = 0; (size_t)i < re->shnum; i++) { 2914 s = &re->sl[i]; 2915 if (s->type != SHT_DYNAMIC) 2916 continue; 2917 (void) elf_errno(); 2918 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 2919 elferr = elf_errno(); 2920 if (elferr != 0) 2921 warnx("elf_getdata failed: %s", elf_errmsg(-1)); 2922 continue; 2923 } 2924 if (d->d_size <= 0) 2925 continue; 2926 2927 is_dynamic = 1; 2928 2929 /* Determine the actual number of table entries. */ 2930 nentries = 0; 2931 jmax = (int) (s->sz / s->entsize); 2932 2933 for (j = 0; j < jmax; j++) { 2934 if (gelf_getdyn(d, j, &dyn) != &dyn) { 2935 warnx("gelf_getdyn failed: %s", 2936 elf_errmsg(-1)); 2937 continue; 2938 } 2939 nentries ++; 2940 if (dyn.d_tag == DT_NULL) 2941 break; 2942 } 2943 2944 printf("\nDynamic section at offset 0x%jx", (uintmax_t)s->off); 2945 printf(" contains %u entries:\n", nentries); 2946 2947 if (re->ec == ELFCLASS32) 2948 printf("%5s%12s%28s\n", "Tag", "Type", "Name/Value"); 2949 else 2950 printf("%5s%20s%28s\n", "Tag", "Type", "Name/Value"); 2951 2952 for (j = 0; j < nentries; j++) { 2953 if (gelf_getdyn(d, j, &dyn) != &dyn) 2954 continue; 2955 /* Dump dynamic entry type. */ 2956 if (re->ec == ELFCLASS32) 2957 printf(" 0x%8.8jx", (uintmax_t)dyn.d_tag); 2958 else 2959 printf(" 0x%16.16jx", (uintmax_t)dyn.d_tag); 2960 printf(" %-20s", dt_type(re->ehdr.e_machine, 2961 dyn.d_tag)); 2962 /* Dump dynamic entry value. */ 2963 dump_dyn_val(re, &dyn, s->link); 2964 } 2965 } 2966 2967 if (!is_dynamic) 2968 printf("\nThere is no dynamic section in this file.\n"); 2969 } 2970 2971 static char * 2972 timestamp(time_t ti) 2973 { 2974 static char ts[32]; 2975 struct tm *t; 2976 2977 t = gmtime(&ti); 2978 snprintf(ts, sizeof(ts), "%04d-%02d-%02dT%02d:%02d:%02d", 2979 t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, 2980 t->tm_min, t->tm_sec); 2981 2982 return (ts); 2983 } 2984 2985 static const char * 2986 dyn_str(struct readelf *re, uint32_t stab, uint64_t d_val) 2987 { 2988 const char *name; 2989 2990 if (stab == SHN_UNDEF) 2991 name = "ERROR"; 2992 else if ((name = elf_strptr(re->elf, stab, d_val)) == NULL) { 2993 (void) elf_errno(); /* clear error */ 2994 name = "ERROR"; 2995 } 2996 2997 return (name); 2998 } 2999 3000 static void 3001 dump_arch_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab) 3002 { 3003 const char *name; 3004 3005 switch (re->ehdr.e_machine) { 3006 case EM_MIPS: 3007 case EM_MIPS_RS3_LE: 3008 switch (dyn->d_tag) { 3009 case DT_MIPS_RLD_VERSION: 3010 case DT_MIPS_LOCAL_GOTNO: 3011 case DT_MIPS_CONFLICTNO: 3012 case DT_MIPS_LIBLISTNO: 3013 case DT_MIPS_SYMTABNO: 3014 case DT_MIPS_UNREFEXTNO: 3015 case DT_MIPS_GOTSYM: 3016 case DT_MIPS_HIPAGENO: 3017 case DT_MIPS_DELTA_CLASS_NO: 3018 case DT_MIPS_DELTA_INSTANCE_NO: 3019 case DT_MIPS_DELTA_RELOC_NO: 3020 case DT_MIPS_DELTA_SYM_NO: 3021 case DT_MIPS_DELTA_CLASSSYM_NO: 3022 case DT_MIPS_LOCALPAGE_GOTIDX: 3023 case DT_MIPS_LOCAL_GOTIDX: 3024 case DT_MIPS_HIDDEN_GOTIDX: 3025 case DT_MIPS_PROTECTED_GOTIDX: 3026 printf(" %ju\n", (uintmax_t) dyn->d_un.d_val); 3027 break; 3028 case DT_MIPS_ICHECKSUM: 3029 case DT_MIPS_FLAGS: 3030 case DT_MIPS_BASE_ADDRESS: 3031 case DT_MIPS_CONFLICT: 3032 case DT_MIPS_LIBLIST: 3033 case DT_MIPS_RLD_MAP: 3034 case DT_MIPS_DELTA_CLASS: 3035 case DT_MIPS_DELTA_INSTANCE: 3036 case DT_MIPS_DELTA_RELOC: 3037 case DT_MIPS_DELTA_SYM: 3038 case DT_MIPS_DELTA_CLASSSYM: 3039 case DT_MIPS_CXX_FLAGS: 3040 case DT_MIPS_PIXIE_INIT: 3041 case DT_MIPS_SYMBOL_LIB: 3042 case DT_MIPS_OPTIONS: 3043 case DT_MIPS_INTERFACE: 3044 case DT_MIPS_DYNSTR_ALIGN: 3045 case DT_MIPS_INTERFACE_SIZE: 3046 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: 3047 case DT_MIPS_COMPACT_SIZE: 3048 case DT_MIPS_GP_VALUE: 3049 case DT_MIPS_AUX_DYNAMIC: 3050 case DT_MIPS_PLTGOT: 3051 case DT_MIPS_RLD_OBJ_UPDATE: 3052 case DT_MIPS_RWPLT: 3053 printf(" 0x%jx\n", (uintmax_t) dyn->d_un.d_val); 3054 break; 3055 case DT_MIPS_IVERSION: 3056 case DT_MIPS_PERF_SUFFIX: 3057 case DT_AUXILIARY: 3058 case DT_FILTER: 3059 name = dyn_str(re, stab, dyn->d_un.d_val); 3060 printf(" %s\n", name); 3061 break; 3062 case DT_MIPS_TIME_STAMP: 3063 printf(" %s\n", timestamp(dyn->d_un.d_val)); 3064 break; 3065 } 3066 break; 3067 default: 3068 printf("\n"); 3069 break; 3070 } 3071 } 3072 3073 static void 3074 dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab) 3075 { 3076 const char *name; 3077 3078 if (dyn->d_tag >= DT_LOPROC && dyn->d_tag <= DT_HIPROC) { 3079 dump_arch_dyn_val(re, dyn, stab); 3080 return; 3081 } 3082 3083 /* These entry values are index into the string table. */ 3084 name = NULL; 3085 if (dyn->d_tag == DT_NEEDED || dyn->d_tag == DT_SONAME || 3086 dyn->d_tag == DT_RPATH || dyn->d_tag == DT_RUNPATH) 3087 name = dyn_str(re, stab, dyn->d_un.d_val); 3088 3089 switch(dyn->d_tag) { 3090 case DT_NULL: 3091 case DT_PLTGOT: 3092 case DT_HASH: 3093 case DT_STRTAB: 3094 case DT_SYMTAB: 3095 case DT_RELA: 3096 case DT_INIT: 3097 case DT_SYMBOLIC: 3098 case DT_REL: 3099 case DT_DEBUG: 3100 case DT_TEXTREL: 3101 case DT_JMPREL: 3102 case DT_FINI: 3103 case DT_VERDEF: 3104 case DT_VERNEED: 3105 case DT_VERSYM: 3106 case DT_GNU_HASH: 3107 case DT_GNU_LIBLIST: 3108 case DT_GNU_CONFLICT: 3109 printf(" 0x%jx\n", (uintmax_t) dyn->d_un.d_val); 3110 break; 3111 case DT_PLTRELSZ: 3112 case DT_RELASZ: 3113 case DT_RELAENT: 3114 case DT_STRSZ: 3115 case DT_SYMENT: 3116 case DT_RELSZ: 3117 case DT_RELENT: 3118 case DT_INIT_ARRAYSZ: 3119 case DT_FINI_ARRAYSZ: 3120 case DT_GNU_CONFLICTSZ: 3121 case DT_GNU_LIBLISTSZ: 3122 printf(" %ju (bytes)\n", (uintmax_t) dyn->d_un.d_val); 3123 break; 3124 case DT_RELACOUNT: 3125 case DT_RELCOUNT: 3126 case DT_VERDEFNUM: 3127 case DT_VERNEEDNUM: 3128 printf(" %ju\n", (uintmax_t) dyn->d_un.d_val); 3129 break; 3130 case DT_NEEDED: 3131 printf(" Shared library: [%s]\n", name); 3132 break; 3133 case DT_SONAME: 3134 printf(" Library soname: [%s]\n", name); 3135 break; 3136 case DT_RPATH: 3137 printf(" Library rpath: [%s]\n", name); 3138 break; 3139 case DT_RUNPATH: 3140 printf(" Library runpath: [%s]\n", name); 3141 break; 3142 case DT_PLTREL: 3143 printf(" %s\n", dt_type(re->ehdr.e_machine, dyn->d_un.d_val)); 3144 break; 3145 case DT_GNU_PRELINKED: 3146 printf(" %s\n", timestamp(dyn->d_un.d_val)); 3147 break; 3148 default: 3149 printf("\n"); 3150 } 3151 } 3152 3153 static void 3154 dump_rel(struct readelf *re, struct section *s, Elf_Data *d) 3155 { 3156 GElf_Rel r; 3157 const char *symname; 3158 uint64_t symval; 3159 int i, len; 3160 3161 #define REL_HDR "r_offset", "r_info", "r_type", "st_value", "st_name" 3162 #define REL_CT32 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ 3163 r_type(re->ehdr.e_machine, ELF32_R_TYPE(r.r_info)), \ 3164 (uintmax_t)symval, symname 3165 #define REL_CT64 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ 3166 r_type(re->ehdr.e_machine, ELF64_R_TYPE(r.r_info)), \ 3167 (uintmax_t)symval, symname 3168 3169 printf("\nRelocation section (%s):\n", s->name); 3170 if (re->ec == ELFCLASS32) 3171 printf("%-8s %-8s %-19s %-8s %s\n", REL_HDR); 3172 else { 3173 if (re->options & RE_WW) 3174 printf("%-16s %-16s %-24s %-16s %s\n", REL_HDR); 3175 else 3176 printf("%-12s %-12s %-19s %-16s %s\n", REL_HDR); 3177 } 3178 len = d->d_size / s->entsize; 3179 for (i = 0; i < len; i++) { 3180 if (gelf_getrel(d, i, &r) != &r) { 3181 warnx("gelf_getrel failed: %s", elf_errmsg(-1)); 3182 continue; 3183 } 3184 if (s->link >= re->shnum) { 3185 warnx("invalid section link index %u", s->link); 3186 continue; 3187 } 3188 symname = get_symbol_name(re, s->link, GELF_R_SYM(r.r_info)); 3189 symval = get_symbol_value(re, s->link, GELF_R_SYM(r.r_info)); 3190 if (re->ec == ELFCLASS32) { 3191 r.r_info = ELF32_R_INFO(ELF64_R_SYM(r.r_info), 3192 ELF64_R_TYPE(r.r_info)); 3193 printf("%8.8jx %8.8jx %-19.19s %8.8jx %s\n", REL_CT32); 3194 } else { 3195 if (re->options & RE_WW) 3196 printf("%16.16jx %16.16jx %-24.24s" 3197 " %16.16jx %s\n", REL_CT64); 3198 else 3199 printf("%12.12jx %12.12jx %-19.19s" 3200 " %16.16jx %s\n", REL_CT64); 3201 } 3202 } 3203 3204 #undef REL_HDR 3205 #undef REL_CT 3206 } 3207 3208 static void 3209 dump_rela(struct readelf *re, struct section *s, Elf_Data *d) 3210 { 3211 GElf_Rela r; 3212 const char *symname; 3213 uint64_t symval; 3214 int i, len; 3215 3216 #define RELA_HDR "r_offset", "r_info", "r_type", "st_value", \ 3217 "st_name + r_addend" 3218 #define RELA_CT32 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ 3219 r_type(re->ehdr.e_machine, ELF32_R_TYPE(r.r_info)), \ 3220 (uintmax_t)symval, symname 3221 #define RELA_CT64 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ 3222 r_type(re->ehdr.e_machine, ELF64_R_TYPE(r.r_info)), \ 3223 (uintmax_t)symval, symname 3224 3225 printf("\nRelocation section with addend (%s):\n", s->name); 3226 if (re->ec == ELFCLASS32) 3227 printf("%-8s %-8s %-19s %-8s %s\n", RELA_HDR); 3228 else { 3229 if (re->options & RE_WW) 3230 printf("%-16s %-16s %-24s %-16s %s\n", RELA_HDR); 3231 else 3232 printf("%-12s %-12s %-19s %-16s %s\n", RELA_HDR); 3233 } 3234 len = d->d_size / s->entsize; 3235 for (i = 0; i < len; i++) { 3236 if (gelf_getrela(d, i, &r) != &r) { 3237 warnx("gelf_getrel failed: %s", elf_errmsg(-1)); 3238 continue; 3239 } 3240 if (s->link >= re->shnum) { 3241 warnx("invalid section link index %u", s->link); 3242 continue; 3243 } 3244 symname = get_symbol_name(re, s->link, GELF_R_SYM(r.r_info)); 3245 symval = get_symbol_value(re, s->link, GELF_R_SYM(r.r_info)); 3246 if (re->ec == ELFCLASS32) { 3247 r.r_info = ELF32_R_INFO(ELF64_R_SYM(r.r_info), 3248 ELF64_R_TYPE(r.r_info)); 3249 printf("%8.8jx %8.8jx %-19.19s %8.8jx %s", RELA_CT32); 3250 printf(" + %x\n", (uint32_t) r.r_addend); 3251 } else { 3252 if (re->options & RE_WW) 3253 printf("%16.16jx %16.16jx %-24.24s" 3254 " %16.16jx %s", RELA_CT64); 3255 else 3256 printf("%12.12jx %12.12jx %-19.19s" 3257 " %16.16jx %s", RELA_CT64); 3258 printf(" + %jx\n", (uintmax_t) r.r_addend); 3259 } 3260 } 3261 3262 #undef RELA_HDR 3263 #undef RELA_CT 3264 } 3265 3266 static void 3267 dump_reloc(struct readelf *re) 3268 { 3269 struct section *s; 3270 Elf_Data *d; 3271 int i, elferr; 3272 3273 for (i = 0; (size_t)i < re->shnum; i++) { 3274 s = &re->sl[i]; 3275 if (s->type == SHT_REL || s->type == SHT_RELA) { 3276 (void) elf_errno(); 3277 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 3278 elferr = elf_errno(); 3279 if (elferr != 0) 3280 warnx("elf_getdata failed: %s", 3281 elf_errmsg(elferr)); 3282 continue; 3283 } 3284 if (s->type == SHT_REL) 3285 dump_rel(re, s, d); 3286 else 3287 dump_rela(re, s, d); 3288 } 3289 } 3290 } 3291 3292 static void 3293 dump_symtab(struct readelf *re, int i) 3294 { 3295 struct section *s; 3296 Elf_Data *d; 3297 GElf_Sym sym; 3298 const char *name; 3299 int elferr, stab, j; 3300 3301 s = &re->sl[i]; 3302 stab = s->link; 3303 (void) elf_errno(); 3304 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 3305 elferr = elf_errno(); 3306 if (elferr != 0) 3307 warnx("elf_getdata failed: %s", elf_errmsg(elferr)); 3308 return; 3309 } 3310 if (d->d_size <= 0) 3311 return; 3312 printf("Symbol table (%s)", s->name); 3313 printf(" contains %ju entries:\n", s->sz / s->entsize); 3314 printf("%7s%9s%14s%5s%8s%6s%9s%5s\n", "Num:", "Value", "Size", "Type", 3315 "Bind", "Vis", "Ndx", "Name"); 3316 3317 for (j = 0; (uint64_t)j < s->sz / s->entsize; j++) { 3318 if (gelf_getsym(d, j, &sym) != &sym) { 3319 warnx("gelf_getsym failed: %s", elf_errmsg(-1)); 3320 continue; 3321 } 3322 printf("%6d:", j); 3323 printf(" %16.16jx", (uintmax_t)sym.st_value); 3324 printf(" %5ju", sym.st_size); 3325 printf(" %-7s", st_type(GELF_ST_TYPE(sym.st_info))); 3326 printf(" %-6s", st_bind(GELF_ST_BIND(sym.st_info))); 3327 printf(" %-8s", st_vis(GELF_ST_VISIBILITY(sym.st_other))); 3328 printf(" %3s", st_shndx(sym.st_shndx)); 3329 if ((name = elf_strptr(re->elf, stab, sym.st_name)) != NULL) 3330 printf(" %s", name); 3331 /* Append symbol version string for SHT_DYNSYM symbol table. */ 3332 if (s->type == SHT_DYNSYM && re->ver != NULL && 3333 re->vs != NULL && re->vs[j] > 1) { 3334 if (re->vs[j] & 0x8000 || 3335 re->ver[re->vs[j] & 0x7fff].type == 0) 3336 printf("@%s (%d)", 3337 re->ver[re->vs[j] & 0x7fff].name, 3338 re->vs[j] & 0x7fff); 3339 else 3340 printf("@@%s (%d)", re->ver[re->vs[j]].name, 3341 re->vs[j]); 3342 } 3343 putchar('\n'); 3344 } 3345 3346 } 3347 3348 static void 3349 dump_symtabs(struct readelf *re) 3350 { 3351 GElf_Dyn dyn; 3352 Elf_Data *d; 3353 struct section *s; 3354 uint64_t dyn_off; 3355 int elferr, i; 3356 3357 /* 3358 * If -D is specified, only dump the symbol table specified by 3359 * the DT_SYMTAB entry in the .dynamic section. 3360 */ 3361 dyn_off = 0; 3362 if (re->options & RE_DD) { 3363 s = NULL; 3364 for (i = 0; (size_t)i < re->shnum; i++) 3365 if (re->sl[i].type == SHT_DYNAMIC) { 3366 s = &re->sl[i]; 3367 break; 3368 } 3369 if (s == NULL) 3370 return; 3371 (void) elf_errno(); 3372 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 3373 elferr = elf_errno(); 3374 if (elferr != 0) 3375 warnx("elf_getdata failed: %s", elf_errmsg(-1)); 3376 return; 3377 } 3378 if (d->d_size <= 0) 3379 return; 3380 3381 for (i = 0; (uint64_t)i < s->sz / s->entsize; i++) { 3382 if (gelf_getdyn(d, i, &dyn) != &dyn) { 3383 warnx("gelf_getdyn failed: %s", elf_errmsg(-1)); 3384 continue; 3385 } 3386 if (dyn.d_tag == DT_SYMTAB) { 3387 dyn_off = dyn.d_un.d_val; 3388 break; 3389 } 3390 } 3391 } 3392 3393 /* Find and dump symbol tables. */ 3394 for (i = 0; (size_t)i < re->shnum; i++) { 3395 s = &re->sl[i]; 3396 if (s->type == SHT_SYMTAB || s->type == SHT_DYNSYM) { 3397 if (re->options & RE_DD) { 3398 if (dyn_off == s->addr) { 3399 dump_symtab(re, i); 3400 break; 3401 } 3402 } else 3403 dump_symtab(re, i); 3404 } 3405 } 3406 } 3407 3408 static void 3409 dump_svr4_hash(struct section *s) 3410 { 3411 Elf_Data *d; 3412 uint32_t *buf; 3413 uint32_t nbucket, nchain; 3414 uint32_t *bucket, *chain; 3415 uint32_t *bl, *c, maxl, total; 3416 int elferr, i, j; 3417 3418 /* Read and parse the content of .hash section. */ 3419 (void) elf_errno(); 3420 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 3421 elferr = elf_errno(); 3422 if (elferr != 0) 3423 warnx("elf_getdata failed: %s", elf_errmsg(elferr)); 3424 return; 3425 } 3426 if (d->d_size < 2 * sizeof(uint32_t)) { 3427 warnx(".hash section too small"); 3428 return; 3429 } 3430 buf = d->d_buf; 3431 nbucket = buf[0]; 3432 nchain = buf[1]; 3433 if (nbucket <= 0 || nchain <= 0) { 3434 warnx("Malformed .hash section"); 3435 return; 3436 } 3437 if (d->d_size != (nbucket + nchain + 2) * sizeof(uint32_t)) { 3438 warnx("Malformed .hash section"); 3439 return; 3440 } 3441 bucket = &buf[2]; 3442 chain = &buf[2 + nbucket]; 3443 3444 maxl = 0; 3445 if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) 3446 errx(EXIT_FAILURE, "calloc failed"); 3447 for (i = 0; (uint32_t)i < nbucket; i++) 3448 for (j = bucket[i]; j > 0 && (uint32_t)j < nchain; j = chain[j]) 3449 if (++bl[i] > maxl) 3450 maxl = bl[i]; 3451 if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) 3452 errx(EXIT_FAILURE, "calloc failed"); 3453 for (i = 0; (uint32_t)i < nbucket; i++) 3454 c[bl[i]]++; 3455 printf("\nHistogram for bucket list length (total of %u buckets):\n", 3456 nbucket); 3457 printf(" Length\tNumber\t\t%% of total\tCoverage\n"); 3458 total = 0; 3459 for (i = 0; (uint32_t)i <= maxl; i++) { 3460 total += c[i] * i; 3461 printf("%7u\t%-10u\t(%5.1f%%)\t%5.1f%%\n", i, c[i], 3462 c[i] * 100.0 / nbucket, total * 100.0 / (nchain - 1)); 3463 } 3464 free(c); 3465 free(bl); 3466 } 3467 3468 static void 3469 dump_svr4_hash64(struct readelf *re, struct section *s) 3470 { 3471 Elf_Data *d, dst; 3472 uint64_t *buf; 3473 uint64_t nbucket, nchain; 3474 uint64_t *bucket, *chain; 3475 uint64_t *bl, *c, maxl, total; 3476 int elferr, i, j; 3477 3478 /* 3479 * ALPHA uses 64-bit hash entries. Since libelf assumes that 3480 * .hash section contains only 32-bit entry, an explicit 3481 * gelf_xlatetom is needed here. 3482 */ 3483 (void) elf_errno(); 3484 if ((d = elf_rawdata(s->scn, NULL)) == NULL) { 3485 elferr = elf_errno(); 3486 if (elferr != 0) 3487 warnx("elf_rawdata failed: %s", 3488 elf_errmsg(elferr)); 3489 return; 3490 } 3491 d->d_type = ELF_T_XWORD; 3492 memcpy(&dst, d, sizeof(Elf_Data)); 3493 if (gelf_xlatetom(re->elf, &dst, d, 3494 re->ehdr.e_ident[EI_DATA]) != &dst) { 3495 warnx("gelf_xlatetom failed: %s", elf_errmsg(-1)); 3496 return; 3497 } 3498 if (dst.d_size < 2 * sizeof(uint64_t)) { 3499 warnx(".hash section too small"); 3500 return; 3501 } 3502 buf = dst.d_buf; 3503 nbucket = buf[0]; 3504 nchain = buf[1]; 3505 if (nbucket <= 0 || nchain <= 0) { 3506 warnx("Malformed .hash section"); 3507 return; 3508 } 3509 if (d->d_size != (nbucket + nchain + 2) * sizeof(uint32_t)) { 3510 warnx("Malformed .hash section"); 3511 return; 3512 } 3513 bucket = &buf[2]; 3514 chain = &buf[2 + nbucket]; 3515 3516 maxl = 0; 3517 if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) 3518 errx(EXIT_FAILURE, "calloc failed"); 3519 for (i = 0; (uint32_t)i < nbucket; i++) 3520 for (j = bucket[i]; j > 0 && (uint32_t)j < nchain; j = chain[j]) 3521 if (++bl[i] > maxl) 3522 maxl = bl[i]; 3523 if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) 3524 errx(EXIT_FAILURE, "calloc failed"); 3525 for (i = 0; (uint64_t)i < nbucket; i++) 3526 c[bl[i]]++; 3527 printf("Histogram for bucket list length (total of %ju buckets):\n", 3528 (uintmax_t)nbucket); 3529 printf(" Length\tNumber\t\t%% of total\tCoverage\n"); 3530 total = 0; 3531 for (i = 0; (uint64_t)i <= maxl; i++) { 3532 total += c[i] * i; 3533 printf("%7u\t%-10ju\t(%5.1f%%)\t%5.1f%%\n", i, (uintmax_t)c[i], 3534 c[i] * 100.0 / nbucket, total * 100.0 / (nchain - 1)); 3535 } 3536 free(c); 3537 free(bl); 3538 } 3539 3540 static void 3541 dump_gnu_hash(struct readelf *re, struct section *s) 3542 { 3543 struct section *ds; 3544 Elf_Data *d; 3545 uint32_t *buf; 3546 uint32_t *bucket, *chain; 3547 uint32_t nbucket, nchain, symndx, maskwords; 3548 uint32_t *bl, *c, maxl, total; 3549 int elferr, dynsymcount, i, j; 3550 3551 (void) elf_errno(); 3552 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 3553 elferr = elf_errno(); 3554 if (elferr != 0) 3555 warnx("elf_getdata failed: %s", 3556 elf_errmsg(elferr)); 3557 return; 3558 } 3559 if (d->d_size < 4 * sizeof(uint32_t)) { 3560 warnx(".gnu.hash section too small"); 3561 return; 3562 } 3563 buf = d->d_buf; 3564 nbucket = buf[0]; 3565 symndx = buf[1]; 3566 maskwords = buf[2]; 3567 buf += 4; 3568 ds = &re->sl[s->link]; 3569 dynsymcount = ds->sz / ds->entsize; 3570 nchain = dynsymcount - symndx; 3571 if (d->d_size != 4 * sizeof(uint32_t) + maskwords * 3572 (re->ec == ELFCLASS32 ? sizeof(uint32_t) : sizeof(uint64_t)) + 3573 (nbucket + nchain) * sizeof(uint32_t)) { 3574 warnx("Malformed .gnu.hash section"); 3575 return; 3576 } 3577 bucket = buf + (re->ec == ELFCLASS32 ? maskwords : maskwords * 2); 3578 chain = bucket + nbucket; 3579 3580 maxl = 0; 3581 if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) 3582 errx(EXIT_FAILURE, "calloc failed"); 3583 for (i = 0; (uint32_t)i < nbucket; i++) 3584 for (j = bucket[i]; j > 0 && (uint32_t)j - symndx < nchain; 3585 j++) { 3586 if (++bl[i] > maxl) 3587 maxl = bl[i]; 3588 if (chain[j - symndx] & 1) 3589 break; 3590 } 3591 if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) 3592 errx(EXIT_FAILURE, "calloc failed"); 3593 for (i = 0; (uint32_t)i < nbucket; i++) 3594 c[bl[i]]++; 3595 printf("Histogram for bucket list length (total of %u buckets):\n", 3596 nbucket); 3597 printf(" Length\tNumber\t\t%% of total\tCoverage\n"); 3598 total = 0; 3599 for (i = 0; (uint32_t)i <= maxl; i++) { 3600 total += c[i] * i; 3601 printf("%7u\t%-10u\t(%5.1f%%)\t%5.1f%%\n", i, c[i], 3602 c[i] * 100.0 / nbucket, total * 100.0 / (nchain - 1)); 3603 } 3604 free(c); 3605 free(bl); 3606 } 3607 3608 static void 3609 dump_hash(struct readelf *re) 3610 { 3611 struct section *s; 3612 int i; 3613 3614 for (i = 0; (size_t) i < re->shnum; i++) { 3615 s = &re->sl[i]; 3616 if (s->type == SHT_HASH || s->type == SHT_GNU_HASH) { 3617 if (s->type == SHT_GNU_HASH) 3618 dump_gnu_hash(re, s); 3619 else if (re->ehdr.e_machine == EM_ALPHA && 3620 s->entsize == 8) 3621 dump_svr4_hash64(re, s); 3622 else 3623 dump_svr4_hash(s); 3624 } 3625 } 3626 } 3627 3628 static void 3629 dump_notes(struct readelf *re) 3630 { 3631 struct section *s; 3632 const char *rawfile; 3633 GElf_Phdr phdr; 3634 Elf_Data *d; 3635 size_t phnum; 3636 int i, elferr; 3637 3638 if (re->ehdr.e_type == ET_CORE) { 3639 /* 3640 * Search program headers in the core file for 3641 * PT_NOTE entry. 3642 */ 3643 if (elf_getphnum(re->elf, &phnum) == 0) { 3644 warnx("elf_getphnum failed: %s", elf_errmsg(-1)); 3645 return; 3646 } 3647 if (phnum == 0) 3648 return; 3649 if ((rawfile = elf_rawfile(re->elf, NULL)) == NULL) { 3650 warnx("elf_rawfile failed: %s", elf_errmsg(-1)); 3651 return; 3652 } 3653 for (i = 0; (size_t) i < phnum; i++) { 3654 if (gelf_getphdr(re->elf, i, &phdr) != &phdr) { 3655 warnx("gelf_getphdr failed: %s", 3656 elf_errmsg(-1)); 3657 continue; 3658 } 3659 if (phdr.p_type == PT_NOTE) 3660 dump_notes_content(re, rawfile + phdr.p_offset, 3661 phdr.p_filesz, phdr.p_offset); 3662 } 3663 3664 } else { 3665 /* 3666 * For objects other than core files, Search for 3667 * SHT_NOTE sections. 3668 */ 3669 for (i = 0; (size_t) i < re->shnum; i++) { 3670 s = &re->sl[i]; 3671 if (s->type == SHT_NOTE) { 3672 (void) elf_errno(); 3673 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 3674 elferr = elf_errno(); 3675 if (elferr != 0) 3676 warnx("elf_getdata failed: %s", 3677 elf_errmsg(elferr)); 3678 continue; 3679 } 3680 dump_notes_content(re, d->d_buf, d->d_size, 3681 s->off); 3682 } 3683 } 3684 } 3685 } 3686 3687 static void 3688 dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off) 3689 { 3690 Elf_Note *note; 3691 const char *end, *name; 3692 3693 printf("\nNotes at offset %#010jx with length %#010jx:\n", 3694 (uintmax_t) off, (uintmax_t) sz); 3695 printf(" %-13s %-15s %s\n", "Owner", "Data size", "Description"); 3696 end = buf + sz; 3697 while (buf < end) { 3698 if (buf + sizeof(*note) > end) { 3699 warnx("invalid note header"); 3700 return; 3701 } 3702 note = (Elf_Note *)(uintptr_t) buf; 3703 name = (char *)(uintptr_t)(note + 1); 3704 /* 3705 * The name field is required to be nul-terminated, and 3706 * n_namesz includes the terminating nul in observed 3707 * implementations (contrary to the ELF-64 spec). A special 3708 * case is needed for cores generated by some older Linux 3709 * versions, which write a note named "CORE" without a nul 3710 * terminator and n_namesz = 4. 3711 */ 3712 if (note->n_namesz == 0) 3713 name = ""; 3714 else if (note->n_namesz == 4 && strncmp(name, "CORE", 4) == 0) 3715 name = "CORE"; 3716 else if (strnlen(name, note->n_namesz) >= note->n_namesz) 3717 name = "<invalid>"; 3718 printf(" %-13s %#010jx", name, (uintmax_t) note->n_descsz); 3719 printf(" %s\n", note_type(name, re->ehdr.e_type, 3720 note->n_type)); 3721 buf += sizeof(Elf_Note) + roundup2(note->n_namesz, 4) + 3722 roundup2(note->n_descsz, 4); 3723 } 3724 } 3725 3726 /* 3727 * Symbol versioning sections are the same for 32bit and 64bit 3728 * ELF objects. 3729 */ 3730 #define Elf_Verdef Elf32_Verdef 3731 #define Elf_Verdaux Elf32_Verdaux 3732 #define Elf_Verneed Elf32_Verneed 3733 #define Elf_Vernaux Elf32_Vernaux 3734 3735 #define SAVE_VERSION_NAME(x, n, t) \ 3736 do { \ 3737 while (x >= re->ver_sz) { \ 3738 nv = realloc(re->ver, \ 3739 sizeof(*re->ver) * re->ver_sz * 2); \ 3740 if (nv == NULL) { \ 3741 warn("realloc failed"); \ 3742 free(re->ver); \ 3743 return; \ 3744 } \ 3745 re->ver = nv; \ 3746 for (i = re->ver_sz; i < re->ver_sz * 2; i++) { \ 3747 re->ver[i].name = NULL; \ 3748 re->ver[i].type = 0; \ 3749 } \ 3750 re->ver_sz *= 2; \ 3751 } \ 3752 if (x > 1) { \ 3753 re->ver[x].name = n; \ 3754 re->ver[x].type = t; \ 3755 } \ 3756 } while (0) 3757 3758 3759 static void 3760 dump_verdef(struct readelf *re, int dump) 3761 { 3762 struct section *s; 3763 struct symver *nv; 3764 Elf_Data *d; 3765 Elf_Verdef *vd; 3766 Elf_Verdaux *vda; 3767 uint8_t *buf, *end, *buf2; 3768 const char *name; 3769 int elferr, i, j; 3770 3771 if ((s = re->vd_s) == NULL) 3772 return; 3773 3774 if (re->ver == NULL) { 3775 re->ver_sz = 16; 3776 if ((re->ver = calloc(re->ver_sz, sizeof(*re->ver))) == 3777 NULL) { 3778 warn("calloc failed"); 3779 return; 3780 } 3781 re->ver[0].name = "*local*"; 3782 re->ver[1].name = "*global*"; 3783 } 3784 3785 if (dump) 3786 printf("\nVersion definition section (%s):\n", s->name); 3787 (void) elf_errno(); 3788 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 3789 elferr = elf_errno(); 3790 if (elferr != 0) 3791 warnx("elf_getdata failed: %s", elf_errmsg(elferr)); 3792 return; 3793 } 3794 if (d->d_size == 0) 3795 return; 3796 3797 buf = d->d_buf; 3798 end = buf + d->d_size; 3799 while (buf + sizeof(Elf_Verdef) <= end) { 3800 vd = (Elf_Verdef *) (uintptr_t) buf; 3801 if (dump) { 3802 printf(" 0x%4.4lx", (unsigned long) 3803 (buf - (uint8_t *)d->d_buf)); 3804 printf(" vd_version: %u vd_flags: %d" 3805 " vd_ndx: %u vd_cnt: %u", vd->vd_version, 3806 vd->vd_flags, vd->vd_ndx, vd->vd_cnt); 3807 } 3808 buf2 = buf + vd->vd_aux; 3809 j = 0; 3810 while (buf2 + sizeof(Elf_Verdaux) <= end && j < vd->vd_cnt) { 3811 vda = (Elf_Verdaux *) (uintptr_t) buf2; 3812 name = get_string(re, s->link, vda->vda_name); 3813 if (j == 0) { 3814 if (dump) 3815 printf(" vda_name: %s\n", name); 3816 SAVE_VERSION_NAME((int)vd->vd_ndx, name, 1); 3817 } else if (dump) 3818 printf(" 0x%4.4lx parent: %s\n", 3819 (unsigned long) (buf2 - 3820 (uint8_t *)d->d_buf), name); 3821 if (vda->vda_next == 0) 3822 break; 3823 buf2 += vda->vda_next; 3824 j++; 3825 } 3826 if (vd->vd_next == 0) 3827 break; 3828 buf += vd->vd_next; 3829 } 3830 } 3831 3832 static void 3833 dump_verneed(struct readelf *re, int dump) 3834 { 3835 struct section *s; 3836 struct symver *nv; 3837 Elf_Data *d; 3838 Elf_Verneed *vn; 3839 Elf_Vernaux *vna; 3840 uint8_t *buf, *end, *buf2; 3841 const char *name; 3842 int elferr, i, j; 3843 3844 if ((s = re->vn_s) == NULL) 3845 return; 3846 3847 if (re->ver == NULL) { 3848 re->ver_sz = 16; 3849 if ((re->ver = calloc(re->ver_sz, sizeof(*re->ver))) == 3850 NULL) { 3851 warn("calloc failed"); 3852 return; 3853 } 3854 re->ver[0].name = "*local*"; 3855 re->ver[1].name = "*global*"; 3856 } 3857 3858 if (dump) 3859 printf("\nVersion needed section (%s):\n", s->name); 3860 (void) elf_errno(); 3861 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 3862 elferr = elf_errno(); 3863 if (elferr != 0) 3864 warnx("elf_getdata failed: %s", elf_errmsg(elferr)); 3865 return; 3866 } 3867 if (d->d_size == 0) 3868 return; 3869 3870 buf = d->d_buf; 3871 end = buf + d->d_size; 3872 while (buf + sizeof(Elf_Verneed) <= end) { 3873 vn = (Elf_Verneed *) (uintptr_t) buf; 3874 if (dump) { 3875 printf(" 0x%4.4lx", (unsigned long) 3876 (buf - (uint8_t *)d->d_buf)); 3877 printf(" vn_version: %u vn_file: %s vn_cnt: %u\n", 3878 vn->vn_version, 3879 get_string(re, s->link, vn->vn_file), 3880 vn->vn_cnt); 3881 } 3882 buf2 = buf + vn->vn_aux; 3883 j = 0; 3884 while (buf2 + sizeof(Elf_Vernaux) <= end && j < vn->vn_cnt) { 3885 vna = (Elf32_Vernaux *) (uintptr_t) buf2; 3886 if (dump) 3887 printf(" 0x%4.4lx", (unsigned long) 3888 (buf2 - (uint8_t *)d->d_buf)); 3889 name = get_string(re, s->link, vna->vna_name); 3890 if (dump) 3891 printf(" vna_name: %s vna_flags: %u" 3892 " vna_other: %u\n", name, 3893 vna->vna_flags, vna->vna_other); 3894 SAVE_VERSION_NAME((int)vna->vna_other, name, 0); 3895 if (vna->vna_next == 0) 3896 break; 3897 buf2 += vna->vna_next; 3898 j++; 3899 } 3900 if (vn->vn_next == 0) 3901 break; 3902 buf += vn->vn_next; 3903 } 3904 } 3905 3906 static void 3907 dump_versym(struct readelf *re) 3908 { 3909 int i; 3910 3911 if (re->vs_s == NULL || re->ver == NULL || re->vs == NULL) 3912 return; 3913 printf("\nVersion symbol section (%s):\n", re->vs_s->name); 3914 for (i = 0; i < re->vs_sz; i++) { 3915 if ((i & 3) == 0) { 3916 if (i > 0) 3917 putchar('\n'); 3918 printf(" %03x:", i); 3919 } 3920 if (re->vs[i] & 0x8000) 3921 printf(" %3xh %-12s ", re->vs[i] & 0x7fff, 3922 re->ver[re->vs[i] & 0x7fff].name); 3923 else 3924 printf(" %3x %-12s ", re->vs[i], 3925 re->ver[re->vs[i]].name); 3926 } 3927 putchar('\n'); 3928 } 3929 3930 static void 3931 dump_ver(struct readelf *re) 3932 { 3933 3934 if (re->vs_s && re->ver && re->vs) 3935 dump_versym(re); 3936 if (re->vd_s) 3937 dump_verdef(re, 1); 3938 if (re->vn_s) 3939 dump_verneed(re, 1); 3940 } 3941 3942 static void 3943 search_ver(struct readelf *re) 3944 { 3945 struct section *s; 3946 Elf_Data *d; 3947 int elferr, i; 3948 3949 for (i = 0; (size_t) i < re->shnum; i++) { 3950 s = &re->sl[i]; 3951 if (s->type == SHT_SUNW_versym) 3952 re->vs_s = s; 3953 if (s->type == SHT_SUNW_verneed) 3954 re->vn_s = s; 3955 if (s->type == SHT_SUNW_verdef) 3956 re->vd_s = s; 3957 } 3958 if (re->vd_s) 3959 dump_verdef(re, 0); 3960 if (re->vn_s) 3961 dump_verneed(re, 0); 3962 if (re->vs_s && re->ver != NULL) { 3963 (void) elf_errno(); 3964 if ((d = elf_getdata(re->vs_s->scn, NULL)) == NULL) { 3965 elferr = elf_errno(); 3966 if (elferr != 0) 3967 warnx("elf_getdata failed: %s", 3968 elf_errmsg(elferr)); 3969 return; 3970 } 3971 if (d->d_size == 0) 3972 return; 3973 re->vs = d->d_buf; 3974 re->vs_sz = d->d_size / sizeof(Elf32_Half); 3975 } 3976 } 3977 3978 #undef Elf_Verdef 3979 #undef Elf_Verdaux 3980 #undef Elf_Verneed 3981 #undef Elf_Vernaux 3982 #undef SAVE_VERSION_NAME 3983 3984 /* 3985 * Elf32_Lib and Elf64_Lib are identical. 3986 */ 3987 #define Elf_Lib Elf32_Lib 3988 3989 static void 3990 dump_liblist(struct readelf *re) 3991 { 3992 struct section *s; 3993 struct tm *t; 3994 time_t ti; 3995 char tbuf[20]; 3996 Elf_Data *d; 3997 Elf_Lib *lib; 3998 int i, j, k, elferr, first; 3999 4000 for (i = 0; (size_t) i < re->shnum; i++) { 4001 s = &re->sl[i]; 4002 if (s->type != SHT_GNU_LIBLIST) 4003 continue; 4004 (void) elf_errno(); 4005 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 4006 elferr = elf_errno(); 4007 if (elferr != 0) 4008 warnx("elf_getdata failed: %s", 4009 elf_errmsg(elferr)); 4010 continue; 4011 } 4012 if (d->d_size <= 0) 4013 continue; 4014 lib = d->d_buf; 4015 printf("\nLibrary list section '%s' ", s->name); 4016 printf("contains %ju entries:\n", s->sz / s->entsize); 4017 printf("%12s%24s%18s%10s%6s\n", "Library", "Time Stamp", 4018 "Checksum", "Version", "Flags"); 4019 for (j = 0; (uint64_t) j < s->sz / s->entsize; j++) { 4020 printf("%3d: ", j); 4021 printf("%-20.20s ", 4022 get_string(re, s->link, lib->l_name)); 4023 ti = lib->l_time_stamp; 4024 t = gmtime(&ti); 4025 snprintf(tbuf, sizeof(tbuf), "%04d-%02d-%02dT%02d:%02d" 4026 ":%2d", t->tm_year + 1900, t->tm_mon + 1, 4027 t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); 4028 printf("%-19.19s ", tbuf); 4029 printf("0x%08x ", lib->l_checksum); 4030 printf("%-7d %#x", lib->l_version, lib->l_flags); 4031 if (lib->l_flags != 0) { 4032 first = 1; 4033 putchar('('); 4034 for (k = 0; l_flag[k].name != NULL; k++) { 4035 if ((l_flag[k].value & lib->l_flags) == 4036 0) 4037 continue; 4038 if (!first) 4039 putchar(','); 4040 else 4041 first = 0; 4042 printf("%s", l_flag[k].name); 4043 } 4044 putchar(')'); 4045 } 4046 putchar('\n'); 4047 lib++; 4048 } 4049 } 4050 } 4051 4052 #undef Elf_Lib 4053 4054 static void 4055 dump_section_groups(struct readelf *re) 4056 { 4057 struct section *s; 4058 const char *symname; 4059 Elf_Data *d; 4060 uint32_t *w; 4061 int i, j, elferr; 4062 size_t n; 4063 4064 for (i = 0; (size_t) i < re->shnum; i++) { 4065 s = &re->sl[i]; 4066 if (s->type != SHT_GROUP) 4067 continue; 4068 (void) elf_errno(); 4069 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 4070 elferr = elf_errno(); 4071 if (elferr != 0) 4072 warnx("elf_getdata failed: %s", 4073 elf_errmsg(elferr)); 4074 continue; 4075 } 4076 if (d->d_size <= 0) 4077 continue; 4078 4079 w = d->d_buf; 4080 4081 /* We only support COMDAT section. */ 4082 #ifndef GRP_COMDAT 4083 #define GRP_COMDAT 0x1 4084 #endif 4085 if ((*w++ & GRP_COMDAT) == 0) 4086 return; 4087 4088 if (s->entsize == 0) 4089 s->entsize = 4; 4090 4091 symname = get_symbol_name(re, s->link, s->info); 4092 n = s->sz / s->entsize; 4093 if (n-- < 1) 4094 return; 4095 4096 printf("\nCOMDAT group section [%5d] `%s' [%s] contains %ju" 4097 " sections:\n", i, s->name, symname, (uintmax_t)n); 4098 printf(" %-10.10s %s\n", "[Index]", "Name"); 4099 for (j = 0; (size_t) j < n; j++, w++) { 4100 if (*w >= re->shnum) { 4101 warnx("invalid section index: %u", *w); 4102 continue; 4103 } 4104 printf(" [%5u] %s\n", *w, re->sl[*w].name); 4105 } 4106 } 4107 } 4108 4109 static uint8_t * 4110 dump_unknown_tag(uint64_t tag, uint8_t *p) 4111 { 4112 uint64_t val; 4113 4114 /* 4115 * According to ARM EABI: For tags > 32, even numbered tags have 4116 * a ULEB128 param and odd numbered ones have NUL-terminated 4117 * string param. This rule probably also applies for tags <= 32 4118 * if the object arch is not ARM. 4119 */ 4120 4121 printf(" Tag_unknown_%ju: ", (uintmax_t) tag); 4122 4123 if (tag & 1) { 4124 printf("%s\n", (char *) p); 4125 p += strlen((char *) p) + 1; 4126 } else { 4127 val = _decode_uleb128(&p); 4128 printf("%ju\n", (uintmax_t) val); 4129 } 4130 4131 return (p); 4132 } 4133 4134 static uint8_t * 4135 dump_compatibility_tag(uint8_t *p) 4136 { 4137 uint64_t val; 4138 4139 val = _decode_uleb128(&p); 4140 printf("flag = %ju, vendor = %s\n", val, p); 4141 p += strlen((char *) p) + 1; 4142 4143 return (p); 4144 } 4145 4146 static void 4147 dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe) 4148 { 4149 uint64_t tag, val; 4150 size_t i; 4151 int found, desc; 4152 4153 (void) re; 4154 4155 while (p < pe) { 4156 tag = _decode_uleb128(&p); 4157 found = desc = 0; 4158 for (i = 0; i < sizeof(aeabi_tags) / sizeof(aeabi_tags[0]); 4159 i++) { 4160 if (tag == aeabi_tags[i].tag) { 4161 found = 1; 4162 printf(" %s: ", aeabi_tags[i].s_tag); 4163 if (aeabi_tags[i].get_desc) { 4164 desc = 1; 4165 val = _decode_uleb128(&p); 4166 printf("%s\n", 4167 aeabi_tags[i].get_desc(val)); 4168 } 4169 break; 4170 } 4171 if (tag < aeabi_tags[i].tag) 4172 break; 4173 } 4174 if (!found) { 4175 p = dump_unknown_tag(tag, p); 4176 continue; 4177 } 4178 if (desc) 4179 continue; 4180 4181 switch (tag) { 4182 case 4: /* Tag_CPU_raw_name */ 4183 case 5: /* Tag_CPU_name */ 4184 case 67: /* Tag_conformance */ 4185 printf("%s\n", (char *) p); 4186 p += strlen((char *) p) + 1; 4187 break; 4188 case 32: /* Tag_compatibility */ 4189 p = dump_compatibility_tag(p); 4190 break; 4191 case 64: /* Tag_nodefaults */ 4192 /* ignored, written as 0. */ 4193 (void) _decode_uleb128(&p); 4194 printf("True\n"); 4195 break; 4196 case 65: /* Tag_also_compatible_with */ 4197 val = _decode_uleb128(&p); 4198 /* Must be Tag_CPU_arch */ 4199 if (val != 6) { 4200 printf("unknown\n"); 4201 break; 4202 } 4203 val = _decode_uleb128(&p); 4204 printf("%s\n", aeabi_cpu_arch(val)); 4205 /* Skip NUL terminator. */ 4206 p++; 4207 break; 4208 default: 4209 putchar('\n'); 4210 break; 4211 } 4212 } 4213 } 4214 4215 #ifndef Tag_GNU_MIPS_ABI_FP 4216 #define Tag_GNU_MIPS_ABI_FP 4 4217 #endif 4218 4219 static void 4220 dump_mips_attributes(struct readelf *re, uint8_t *p, uint8_t *pe) 4221 { 4222 uint64_t tag, val; 4223 4224 (void) re; 4225 4226 while (p < pe) { 4227 tag = _decode_uleb128(&p); 4228 switch (tag) { 4229 case Tag_GNU_MIPS_ABI_FP: 4230 val = _decode_uleb128(&p); 4231 printf(" Tag_GNU_MIPS_ABI_FP: %s\n", mips_abi_fp(val)); 4232 break; 4233 case 32: /* Tag_compatibility */ 4234 p = dump_compatibility_tag(p); 4235 break; 4236 default: 4237 p = dump_unknown_tag(tag, p); 4238 break; 4239 } 4240 } 4241 } 4242 4243 #ifndef Tag_GNU_Power_ABI_FP 4244 #define Tag_GNU_Power_ABI_FP 4 4245 #endif 4246 4247 #ifndef Tag_GNU_Power_ABI_Vector 4248 #define Tag_GNU_Power_ABI_Vector 8 4249 #endif 4250 4251 static void 4252 dump_ppc_attributes(uint8_t *p, uint8_t *pe) 4253 { 4254 uint64_t tag, val; 4255 4256 while (p < pe) { 4257 tag = _decode_uleb128(&p); 4258 switch (tag) { 4259 case Tag_GNU_Power_ABI_FP: 4260 val = _decode_uleb128(&p); 4261 printf(" Tag_GNU_Power_ABI_FP: %s\n", ppc_abi_fp(val)); 4262 break; 4263 case Tag_GNU_Power_ABI_Vector: 4264 val = _decode_uleb128(&p); 4265 printf(" Tag_GNU_Power_ABI_Vector: %s\n", 4266 ppc_abi_vector(val)); 4267 break; 4268 case 32: /* Tag_compatibility */ 4269 p = dump_compatibility_tag(p); 4270 break; 4271 default: 4272 p = dump_unknown_tag(tag, p); 4273 break; 4274 } 4275 } 4276 } 4277 4278 static void 4279 dump_attributes(struct readelf *re) 4280 { 4281 struct section *s; 4282 Elf_Data *d; 4283 uint8_t *p, *sp; 4284 size_t len, seclen, nlen, sublen; 4285 uint64_t val; 4286 int tag, i, elferr; 4287 4288 for (i = 0; (size_t) i < re->shnum; i++) { 4289 s = &re->sl[i]; 4290 if (s->type != SHT_GNU_ATTRIBUTES && 4291 (re->ehdr.e_machine != EM_ARM || s->type != SHT_LOPROC + 3)) 4292 continue; 4293 (void) elf_errno(); 4294 if ((d = elf_rawdata(s->scn, NULL)) == NULL) { 4295 elferr = elf_errno(); 4296 if (elferr != 0) 4297 warnx("elf_rawdata failed: %s", 4298 elf_errmsg(elferr)); 4299 continue; 4300 } 4301 if (d->d_size <= 0) 4302 continue; 4303 p = d->d_buf; 4304 if (*p != 'A') { 4305 printf("Unknown Attribute Section Format: %c\n", 4306 (char) *p); 4307 continue; 4308 } 4309 len = d->d_size - 1; 4310 p++; 4311 while (len > 0) { 4312 if (len < 4) { 4313 warnx("truncated attribute section length"); 4314 break; 4315 } 4316 seclen = re->dw_decode(&p, 4); 4317 if (seclen > len) { 4318 warnx("invalid attribute section length"); 4319 break; 4320 } 4321 len -= seclen; 4322 nlen = strlen((char *) p) + 1; 4323 if (nlen + 4 > seclen) { 4324 warnx("invalid attribute section name"); 4325 break; 4326 } 4327 printf("Attribute Section: %s\n", (char *) p); 4328 p += nlen; 4329 seclen -= nlen + 4; 4330 while (seclen > 0) { 4331 sp = p; 4332 tag = *p++; 4333 sublen = re->dw_decode(&p, 4); 4334 if (sublen > seclen) { 4335 warnx("invalid attribute sub-section" 4336 " length"); 4337 break; 4338 } 4339 seclen -= sublen; 4340 printf("%s", top_tag(tag)); 4341 if (tag == 2 || tag == 3) { 4342 putchar(':'); 4343 for (;;) { 4344 val = _decode_uleb128(&p); 4345 if (val == 0) 4346 break; 4347 printf(" %ju", (uintmax_t) val); 4348 } 4349 } 4350 putchar('\n'); 4351 if (re->ehdr.e_machine == EM_ARM && 4352 s->type == SHT_LOPROC + 3) 4353 dump_arm_attributes(re, p, sp + sublen); 4354 else if (re->ehdr.e_machine == EM_MIPS || 4355 re->ehdr.e_machine == EM_MIPS_RS3_LE) 4356 dump_mips_attributes(re, p, 4357 sp + sublen); 4358 else if (re->ehdr.e_machine == EM_PPC) 4359 dump_ppc_attributes(p, sp + sublen); 4360 p = sp + sublen; 4361 } 4362 } 4363 } 4364 } 4365 4366 static void 4367 dump_mips_specific_info(struct readelf *re) 4368 { 4369 struct section *s; 4370 int i, options_found; 4371 4372 options_found = 0; 4373 s = NULL; 4374 for (i = 0; (size_t) i < re->shnum; i++) { 4375 s = &re->sl[i]; 4376 if (s->name != NULL && (!strcmp(s->name, ".MIPS.options") || 4377 (s->type == SHT_MIPS_OPTIONS))) { 4378 dump_mips_options(re, s); 4379 options_found = 1; 4380 } 4381 } 4382 4383 /* 4384 * According to SGI mips64 spec, .reginfo should be ignored if 4385 * .MIPS.options section is present. 4386 */ 4387 if (!options_found) { 4388 for (i = 0; (size_t) i < re->shnum; i++) { 4389 s = &re->sl[i]; 4390 if (s->name != NULL && (!strcmp(s->name, ".reginfo") || 4391 (s->type == SHT_MIPS_REGINFO))) 4392 dump_mips_reginfo(re, s); 4393 } 4394 } 4395 } 4396 4397 static void 4398 dump_mips_reginfo(struct readelf *re, struct section *s) 4399 { 4400 Elf_Data *d; 4401 int elferr; 4402 4403 (void) elf_errno(); 4404 if ((d = elf_rawdata(s->scn, NULL)) == NULL) { 4405 elferr = elf_errno(); 4406 if (elferr != 0) 4407 warnx("elf_rawdata failed: %s", 4408 elf_errmsg(elferr)); 4409 return; 4410 } 4411 if (d->d_size <= 0) 4412 return; 4413 4414 printf("\nSection '%s' contains %ju entries:\n", s->name, 4415 s->sz / s->entsize); 4416 dump_mips_odk_reginfo(re, d->d_buf, d->d_size); 4417 } 4418 4419 static void 4420 dump_mips_options(struct readelf *re, struct section *s) 4421 { 4422 Elf_Data *d; 4423 uint32_t info; 4424 uint16_t sndx; 4425 uint8_t *p, *pe; 4426 uint8_t kind, size; 4427 int elferr; 4428 4429 (void) elf_errno(); 4430 if ((d = elf_rawdata(s->scn, NULL)) == NULL) { 4431 elferr = elf_errno(); 4432 if (elferr != 0) 4433 warnx("elf_rawdata failed: %s", 4434 elf_errmsg(elferr)); 4435 return; 4436 } 4437 if (d->d_size == 0) 4438 return; 4439 4440 printf("\nSection %s contains:\n", s->name); 4441 p = d->d_buf; 4442 pe = p + d->d_size; 4443 while (p < pe) { 4444 if (pe - p < 8) { 4445 warnx("Truncated MIPS option header"); 4446 return; 4447 } 4448 kind = re->dw_decode(&p, 1); 4449 size = re->dw_decode(&p, 1); 4450 sndx = re->dw_decode(&p, 2); 4451 info = re->dw_decode(&p, 4); 4452 if (size < 8 || size - 8 > pe - p) { 4453 warnx("Malformed MIPS option header"); 4454 return; 4455 } 4456 size -= 8; 4457 switch (kind) { 4458 case ODK_REGINFO: 4459 dump_mips_odk_reginfo(re, p, size); 4460 break; 4461 case ODK_EXCEPTIONS: 4462 printf(" EXCEPTIONS FPU_MIN: %#x\n", 4463 info & OEX_FPU_MIN); 4464 printf("%11.11s FPU_MAX: %#x\n", "", 4465 info & OEX_FPU_MAX); 4466 dump_mips_option_flags("", mips_exceptions_option, 4467 info); 4468 break; 4469 case ODK_PAD: 4470 printf(" %-10.10s section: %ju\n", "OPAD", 4471 (uintmax_t) sndx); 4472 dump_mips_option_flags("", mips_pad_option, info); 4473 break; 4474 case ODK_HWPATCH: 4475 dump_mips_option_flags("HWPATCH", mips_hwpatch_option, 4476 info); 4477 break; 4478 case ODK_HWAND: 4479 dump_mips_option_flags("HWAND", mips_hwa_option, info); 4480 break; 4481 case ODK_HWOR: 4482 dump_mips_option_flags("HWOR", mips_hwo_option, info); 4483 break; 4484 case ODK_FILL: 4485 printf(" %-10.10s %#jx\n", "FILL", (uintmax_t) info); 4486 break; 4487 case ODK_TAGS: 4488 printf(" %-10.10s\n", "TAGS"); 4489 break; 4490 case ODK_GP_GROUP: 4491 printf(" %-10.10s GP group number: %#x\n", "GP_GROUP", 4492 info & 0xFFFF); 4493 if (info & 0x10000) 4494 printf(" %-10.10s GP group is " 4495 "self-contained\n", ""); 4496 break; 4497 case ODK_IDENT: 4498 printf(" %-10.10s default GP group number: %#x\n", 4499 "IDENT", info & 0xFFFF); 4500 if (info & 0x10000) 4501 printf(" %-10.10s default GP group is " 4502 "self-contained\n", ""); 4503 break; 4504 case ODK_PAGESIZE: 4505 printf(" %-10.10s\n", "PAGESIZE"); 4506 break; 4507 default: 4508 break; 4509 } 4510 p += size; 4511 } 4512 } 4513 4514 static void 4515 dump_mips_option_flags(const char *name, struct mips_option *opt, uint64_t info) 4516 { 4517 int first; 4518 4519 first = 1; 4520 for (; opt->desc != NULL; opt++) { 4521 if (info & opt->flag) { 4522 printf(" %-10.10s %s\n", first ? name : "", 4523 opt->desc); 4524 first = 0; 4525 } 4526 } 4527 } 4528 4529 static void 4530 dump_mips_odk_reginfo(struct readelf *re, uint8_t *p, size_t sz) 4531 { 4532 uint32_t ri_gprmask; 4533 uint32_t ri_cprmask[4]; 4534 uint64_t ri_gp_value; 4535 uint8_t *pe; 4536 int i; 4537 4538 pe = p + sz; 4539 while (p < pe) { 4540 ri_gprmask = re->dw_decode(&p, 4); 4541 /* Skip ri_pad padding field for mips64. */ 4542 if (re->ec == ELFCLASS64) 4543 re->dw_decode(&p, 4); 4544 for (i = 0; i < 4; i++) 4545 ri_cprmask[i] = re->dw_decode(&p, 4); 4546 if (re->ec == ELFCLASS32) 4547 ri_gp_value = re->dw_decode(&p, 4); 4548 else 4549 ri_gp_value = re->dw_decode(&p, 8); 4550 printf(" %s ", option_kind(ODK_REGINFO)); 4551 printf("ri_gprmask: 0x%08jx\n", (uintmax_t) ri_gprmask); 4552 for (i = 0; i < 4; i++) 4553 printf("%11.11s ri_cprmask[%d]: 0x%08jx\n", "", i, 4554 (uintmax_t) ri_cprmask[i]); 4555 printf("%12.12s", ""); 4556 printf("ri_gp_value: %#jx\n", (uintmax_t) ri_gp_value); 4557 } 4558 } 4559 4560 static void 4561 dump_arch_specific_info(struct readelf *re) 4562 { 4563 4564 dump_liblist(re); 4565 dump_attributes(re); 4566 4567 switch (re->ehdr.e_machine) { 4568 case EM_MIPS: 4569 case EM_MIPS_RS3_LE: 4570 dump_mips_specific_info(re); 4571 default: 4572 break; 4573 } 4574 } 4575 4576 static const char * 4577 dwarf_regname(struct readelf *re, unsigned int num) 4578 { 4579 static char rx[32]; 4580 const char *rn; 4581 4582 if ((rn = dwarf_reg(re->ehdr.e_machine, num)) != NULL) 4583 return (rn); 4584 4585 snprintf(rx, sizeof(rx), "r%u", num); 4586 4587 return (rx); 4588 } 4589 4590 static void 4591 dump_dwarf_line(struct readelf *re) 4592 { 4593 struct section *s; 4594 Dwarf_Die die; 4595 Dwarf_Error de; 4596 Dwarf_Half tag, version, pointer_size; 4597 Dwarf_Unsigned offset, endoff, length, hdrlen, dirndx, mtime, fsize; 4598 Dwarf_Small minlen, defstmt, lrange, opbase, oplen; 4599 Elf_Data *d; 4600 char *pn; 4601 uint64_t address, file, line, column, isa, opsize, udelta; 4602 int64_t sdelta; 4603 uint8_t *p, *pe; 4604 int8_t lbase; 4605 int i, is_stmt, dwarf_size, elferr, ret; 4606 4607 printf("\nDump of debug contents of section .debug_line:\n"); 4608 4609 s = NULL; 4610 for (i = 0; (size_t) i < re->shnum; i++) { 4611 s = &re->sl[i]; 4612 if (s->name != NULL && !strcmp(s->name, ".debug_line")) 4613 break; 4614 } 4615 if ((size_t) i >= re->shnum) 4616 return; 4617 4618 (void) elf_errno(); 4619 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 4620 elferr = elf_errno(); 4621 if (elferr != 0) 4622 warnx("elf_getdata failed: %s", elf_errmsg(-1)); 4623 return; 4624 } 4625 if (d->d_size <= 0) 4626 return; 4627 4628 while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, NULL, NULL, 4629 NULL, &de)) == DW_DLV_OK) { 4630 die = NULL; 4631 while (dwarf_siblingof(re->dbg, die, &die, &de) == DW_DLV_OK) { 4632 if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { 4633 warnx("dwarf_tag failed: %s", 4634 dwarf_errmsg(de)); 4635 return; 4636 } 4637 /* XXX: What about DW_TAG_partial_unit? */ 4638 if (tag == DW_TAG_compile_unit) 4639 break; 4640 } 4641 if (die == NULL) { 4642 warnx("could not find DW_TAG_compile_unit die"); 4643 return; 4644 } 4645 if (dwarf_attrval_unsigned(die, DW_AT_stmt_list, &offset, 4646 &de) != DW_DLV_OK) 4647 continue; 4648 4649 length = re->dw_read(d, &offset, 4); 4650 if (length == 0xffffffff) { 4651 dwarf_size = 8; 4652 length = re->dw_read(d, &offset, 8); 4653 } else 4654 dwarf_size = 4; 4655 4656 if (length > d->d_size - offset) { 4657 warnx("invalid .dwarf_line section"); 4658 continue; 4659 } 4660 4661 endoff = offset + length; 4662 version = re->dw_read(d, &offset, 2); 4663 hdrlen = re->dw_read(d, &offset, dwarf_size); 4664 minlen = re->dw_read(d, &offset, 1); 4665 defstmt = re->dw_read(d, &offset, 1); 4666 lbase = re->dw_read(d, &offset, 1); 4667 lrange = re->dw_read(d, &offset, 1); 4668 opbase = re->dw_read(d, &offset, 1); 4669 4670 printf("\n"); 4671 printf(" Length:\t\t\t%ju\n", (uintmax_t) length); 4672 printf(" DWARF version:\t\t%u\n", version); 4673 printf(" Prologue Length:\t\t%ju\n", (uintmax_t) hdrlen); 4674 printf(" Minimum Instruction Length:\t%u\n", minlen); 4675 printf(" Initial value of 'is_stmt':\t%u\n", defstmt); 4676 printf(" Line Base:\t\t\t%d\n", lbase); 4677 printf(" Line Range:\t\t\t%u\n", lrange); 4678 printf(" Opcode Base:\t\t\t%u\n", opbase); 4679 (void) dwarf_get_address_size(re->dbg, &pointer_size, &de); 4680 printf(" (Pointer size:\t\t%u)\n", pointer_size); 4681 4682 printf("\n"); 4683 printf(" Opcodes:\n"); 4684 for (i = 1; i < opbase; i++) { 4685 oplen = re->dw_read(d, &offset, 1); 4686 printf(" Opcode %d has %u args\n", i, oplen); 4687 } 4688 4689 printf("\n"); 4690 printf(" The Directory Table:\n"); 4691 p = (uint8_t *) d->d_buf + offset; 4692 while (*p != '\0') { 4693 printf(" %s\n", (char *) p); 4694 p += strlen((char *) p) + 1; 4695 } 4696 4697 p++; 4698 printf("\n"); 4699 printf(" The File Name Table:\n"); 4700 printf(" Entry\tDir\tTime\tSize\tName\n"); 4701 i = 0; 4702 while (*p != '\0') { 4703 i++; 4704 pn = (char *) p; 4705 p += strlen(pn) + 1; 4706 dirndx = _decode_uleb128(&p); 4707 mtime = _decode_uleb128(&p); 4708 fsize = _decode_uleb128(&p); 4709 printf(" %d\t%ju\t%ju\t%ju\t%s\n", i, 4710 (uintmax_t) dirndx, (uintmax_t) mtime, 4711 (uintmax_t) fsize, pn); 4712 } 4713 4714 #define RESET_REGISTERS \ 4715 do { \ 4716 address = 0; \ 4717 file = 1; \ 4718 line = 1; \ 4719 column = 0; \ 4720 is_stmt = defstmt; \ 4721 } while(0) 4722 4723 #define LINE(x) (lbase + (((x) - opbase) % lrange)) 4724 #define ADDRESS(x) ((((x) - opbase) / lrange) * minlen) 4725 4726 p++; 4727 pe = (uint8_t *) d->d_buf + endoff; 4728 printf("\n"); 4729 printf(" Line Number Statements:\n"); 4730 4731 RESET_REGISTERS; 4732 4733 while (p < pe) { 4734 4735 if (*p == 0) { 4736 /* 4737 * Extended Opcodes. 4738 */ 4739 p++; 4740 opsize = _decode_uleb128(&p); 4741 printf(" Extended opcode %u: ", *p); 4742 switch (*p) { 4743 case DW_LNE_end_sequence: 4744 p++; 4745 RESET_REGISTERS; 4746 printf("End of Sequence\n"); 4747 break; 4748 case DW_LNE_set_address: 4749 p++; 4750 address = re->dw_decode(&p, 4751 pointer_size); 4752 printf("set Address to %#jx\n", 4753 (uintmax_t) address); 4754 break; 4755 case DW_LNE_define_file: 4756 p++; 4757 pn = (char *) p; 4758 p += strlen(pn) + 1; 4759 dirndx = _decode_uleb128(&p); 4760 mtime = _decode_uleb128(&p); 4761 fsize = _decode_uleb128(&p); 4762 printf("define new file: %s\n", pn); 4763 break; 4764 default: 4765 /* Unrecognized extened opcodes. */ 4766 p += opsize; 4767 printf("unknown opcode\n"); 4768 } 4769 } else if (*p > 0 && *p < opbase) { 4770 /* 4771 * Standard Opcodes. 4772 */ 4773 switch(*p++) { 4774 case DW_LNS_copy: 4775 printf(" Copy\n"); 4776 break; 4777 case DW_LNS_advance_pc: 4778 udelta = _decode_uleb128(&p) * 4779 minlen; 4780 address += udelta; 4781 printf(" Advance PC by %ju to %#jx\n", 4782 (uintmax_t) udelta, 4783 (uintmax_t) address); 4784 break; 4785 case DW_LNS_advance_line: 4786 sdelta = _decode_sleb128(&p); 4787 line += sdelta; 4788 printf(" Advance Line by %jd to %ju\n", 4789 (intmax_t) sdelta, 4790 (uintmax_t) line); 4791 break; 4792 case DW_LNS_set_file: 4793 file = _decode_uleb128(&p); 4794 printf(" Set File to %ju\n", 4795 (uintmax_t) file); 4796 break; 4797 case DW_LNS_set_column: 4798 column = _decode_uleb128(&p); 4799 printf(" Set Column to %ju\n", 4800 (uintmax_t) column); 4801 break; 4802 case DW_LNS_negate_stmt: 4803 is_stmt = !is_stmt; 4804 printf(" Set is_stmt to %d\n", is_stmt); 4805 break; 4806 case DW_LNS_set_basic_block: 4807 printf(" Set basic block flag\n"); 4808 break; 4809 case DW_LNS_const_add_pc: 4810 address += ADDRESS(255); 4811 printf(" Advance PC by constant %ju" 4812 " to %#jx\n", 4813 (uintmax_t) ADDRESS(255), 4814 (uintmax_t) address); 4815 break; 4816 case DW_LNS_fixed_advance_pc: 4817 udelta = re->dw_decode(&p, 2); 4818 address += udelta; 4819 printf(" Advance PC by fixed value " 4820 "%ju to %#jx\n", 4821 (uintmax_t) udelta, 4822 (uintmax_t) address); 4823 break; 4824 case DW_LNS_set_prologue_end: 4825 printf(" Set prologue end flag\n"); 4826 break; 4827 case DW_LNS_set_epilogue_begin: 4828 printf(" Set epilogue begin flag\n"); 4829 break; 4830 case DW_LNS_set_isa: 4831 isa = _decode_uleb128(&p); 4832 printf(" Set isa to %ju\n", isa); 4833 break; 4834 default: 4835 /* Unrecognized extended opcodes. */ 4836 printf(" Unknown extended opcode %u\n", 4837 *(p - 1)); 4838 break; 4839 } 4840 4841 } else { 4842 /* 4843 * Special Opcodes. 4844 */ 4845 line += LINE(*p); 4846 address += ADDRESS(*p); 4847 printf(" Special opcode %u: advance Address " 4848 "by %ju to %#jx and Line by %jd to %ju\n", 4849 *p - opbase, (uintmax_t) ADDRESS(*p), 4850 (uintmax_t) address, (intmax_t) LINE(*p), 4851 (uintmax_t) line); 4852 p++; 4853 } 4854 4855 4856 } 4857 } 4858 if (ret == DW_DLV_ERROR) 4859 warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); 4860 4861 #undef RESET_REGISTERS 4862 #undef LINE 4863 #undef ADDRESS 4864 } 4865 4866 static void 4867 dump_dwarf_line_decoded(struct readelf *re) 4868 { 4869 Dwarf_Die die; 4870 Dwarf_Line *linebuf, ln; 4871 Dwarf_Addr lineaddr; 4872 Dwarf_Signed linecount, srccount; 4873 Dwarf_Unsigned lineno, fn; 4874 Dwarf_Error de; 4875 const char *dir, *file; 4876 char **srcfiles; 4877 int i, ret; 4878 4879 printf("Decoded dump of debug contents of section .debug_line:\n\n"); 4880 while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, NULL, NULL, 4881 NULL, &de)) == DW_DLV_OK) { 4882 if (dwarf_siblingof(re->dbg, NULL, &die, &de) != DW_DLV_OK) 4883 continue; 4884 if (dwarf_attrval_string(die, DW_AT_name, &file, &de) != 4885 DW_DLV_OK) 4886 file = NULL; 4887 if (dwarf_attrval_string(die, DW_AT_comp_dir, &dir, &de) != 4888 DW_DLV_OK) 4889 dir = NULL; 4890 printf("CU: "); 4891 if (dir && file) 4892 printf("%s/", dir); 4893 if (file) 4894 printf("%s", file); 4895 putchar('\n'); 4896 printf("%-37s %11s %s\n", "Filename", "Line Number", 4897 "Starting Address"); 4898 if (dwarf_srclines(die, &linebuf, &linecount, &de) != DW_DLV_OK) 4899 continue; 4900 if (dwarf_srcfiles(die, &srcfiles, &srccount, &de) != DW_DLV_OK) 4901 continue; 4902 for (i = 0; i < linecount; i++) { 4903 ln = linebuf[i]; 4904 if (dwarf_line_srcfileno(ln, &fn, &de) != DW_DLV_OK) 4905 continue; 4906 if (dwarf_lineno(ln, &lineno, &de) != DW_DLV_OK) 4907 continue; 4908 if (dwarf_lineaddr(ln, &lineaddr, &de) != DW_DLV_OK) 4909 continue; 4910 printf("%-37s %11ju %#18jx\n", 4911 basename(srcfiles[fn - 1]), (uintmax_t) lineno, 4912 (uintmax_t) lineaddr); 4913 } 4914 putchar('\n'); 4915 } 4916 } 4917 4918 static void 4919 dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) 4920 { 4921 Dwarf_Attribute *attr_list; 4922 Dwarf_Die ret_die; 4923 Dwarf_Off dieoff, cuoff, culen, attroff; 4924 Dwarf_Unsigned ate, lang, v_udata, v_sig; 4925 Dwarf_Signed attr_count, v_sdata; 4926 Dwarf_Off v_off; 4927 Dwarf_Addr v_addr; 4928 Dwarf_Half tag, attr, form; 4929 Dwarf_Block *v_block; 4930 Dwarf_Bool v_bool, is_info; 4931 Dwarf_Sig8 v_sig8; 4932 Dwarf_Error de; 4933 Dwarf_Ptr v_expr; 4934 const char *tag_str, *attr_str, *ate_str, *lang_str; 4935 char unk_tag[32], unk_attr[32]; 4936 char *v_str; 4937 uint8_t *b, *p; 4938 int i, j, abc, ret; 4939 4940 if (dwarf_dieoffset(die, &dieoff, &de) != DW_DLV_OK) { 4941 warnx("dwarf_dieoffset failed: %s", dwarf_errmsg(de)); 4942 goto cont_search; 4943 } 4944 4945 printf(" <%d><%jx>: ", level, (uintmax_t) dieoff); 4946 4947 if (dwarf_die_CU_offset_range(die, &cuoff, &culen, &de) != DW_DLV_OK) { 4948 warnx("dwarf_die_CU_offset_range failed: %s", 4949 dwarf_errmsg(de)); 4950 cuoff = 0; 4951 } 4952 4953 abc = dwarf_die_abbrev_code(die); 4954 if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { 4955 warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); 4956 goto cont_search; 4957 } 4958 if (dwarf_get_TAG_name(tag, &tag_str) != DW_DLV_OK) { 4959 snprintf(unk_tag, sizeof(unk_tag), "[Unknown Tag: %#x]", tag); 4960 tag_str = unk_tag; 4961 } 4962 4963 printf("Abbrev Number: %d (%s)\n", abc, tag_str); 4964 4965 if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != 4966 DW_DLV_OK) { 4967 if (ret == DW_DLV_ERROR) 4968 warnx("dwarf_attrlist failed: %s", dwarf_errmsg(de)); 4969 goto cont_search; 4970 } 4971 4972 for (i = 0; i < attr_count; i++) { 4973 if (dwarf_whatform(attr_list[i], &form, &de) != DW_DLV_OK) { 4974 warnx("dwarf_whatform failed: %s", dwarf_errmsg(de)); 4975 continue; 4976 } 4977 if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { 4978 warnx("dwarf_whatattr failed: %s", dwarf_errmsg(de)); 4979 continue; 4980 } 4981 if (dwarf_get_AT_name(attr, &attr_str) != DW_DLV_OK) { 4982 snprintf(unk_attr, sizeof(unk_attr), 4983 "[Unknown AT: %#x]", attr); 4984 attr_str = unk_attr; 4985 } 4986 if (dwarf_attroffset(attr_list[i], &attroff, &de) != 4987 DW_DLV_OK) { 4988 warnx("dwarf_attroffset failed: %s", dwarf_errmsg(de)); 4989 attroff = 0; 4990 } 4991 printf(" <%jx> %-18s: ", (uintmax_t) attroff, attr_str); 4992 switch (form) { 4993 case DW_FORM_ref_addr: 4994 case DW_FORM_sec_offset: 4995 if (dwarf_global_formref(attr_list[i], &v_off, &de) != 4996 DW_DLV_OK) { 4997 warnx("dwarf_global_formref failed: %s", 4998 dwarf_errmsg(de)); 4999 continue; 5000 } 5001 if (form == DW_FORM_ref_addr) 5002 printf("<0x%jx>", (uintmax_t) v_off); 5003 else 5004 printf("0x%jx", (uintmax_t) v_off); 5005 break; 5006 5007 case DW_FORM_ref1: 5008 case DW_FORM_ref2: 5009 case DW_FORM_ref4: 5010 case DW_FORM_ref8: 5011 case DW_FORM_ref_udata: 5012 if (dwarf_formref(attr_list[i], &v_off, &de) != 5013 DW_DLV_OK) { 5014 warnx("dwarf_formref failed: %s", 5015 dwarf_errmsg(de)); 5016 continue; 5017 } 5018 v_off += cuoff; 5019 printf("<0x%jx>", (uintmax_t) v_off); 5020 break; 5021 5022 case DW_FORM_addr: 5023 if (dwarf_formaddr(attr_list[i], &v_addr, &de) != 5024 DW_DLV_OK) { 5025 warnx("dwarf_formaddr failed: %s", 5026 dwarf_errmsg(de)); 5027 continue; 5028 } 5029 printf("%#jx", (uintmax_t) v_addr); 5030 break; 5031 5032 case DW_FORM_data1: 5033 case DW_FORM_data2: 5034 case DW_FORM_data4: 5035 case DW_FORM_data8: 5036 case DW_FORM_udata: 5037 if (dwarf_formudata(attr_list[i], &v_udata, &de) != 5038 DW_DLV_OK) { 5039 warnx("dwarf_formudata failed: %s", 5040 dwarf_errmsg(de)); 5041 continue; 5042 } 5043 if (attr == DW_AT_high_pc) 5044 printf("0x%jx", (uintmax_t) v_udata); 5045 else 5046 printf("%ju", (uintmax_t) v_udata); 5047 break; 5048 5049 case DW_FORM_sdata: 5050 if (dwarf_formsdata(attr_list[i], &v_sdata, &de) != 5051 DW_DLV_OK) { 5052 warnx("dwarf_formudata failed: %s", 5053 dwarf_errmsg(de)); 5054 continue; 5055 } 5056 printf("%jd", (intmax_t) v_sdata); 5057 break; 5058 5059 case DW_FORM_flag: 5060 if (dwarf_formflag(attr_list[i], &v_bool, &de) != 5061 DW_DLV_OK) { 5062 warnx("dwarf_formflag failed: %s", 5063 dwarf_errmsg(de)); 5064 continue; 5065 } 5066 printf("%jd", (intmax_t) v_bool); 5067 break; 5068 5069 case DW_FORM_flag_present: 5070 putchar('1'); 5071 break; 5072 5073 case DW_FORM_string: 5074 case DW_FORM_strp: 5075 if (dwarf_formstring(attr_list[i], &v_str, &de) != 5076 DW_DLV_OK) { 5077 warnx("dwarf_formstring failed: %s", 5078 dwarf_errmsg(de)); 5079 continue; 5080 } 5081 if (form == DW_FORM_string) 5082 printf("%s", v_str); 5083 else 5084 printf("(indirect string) %s", v_str); 5085 break; 5086 5087 case DW_FORM_block: 5088 case DW_FORM_block1: 5089 case DW_FORM_block2: 5090 case DW_FORM_block4: 5091 if (dwarf_formblock(attr_list[i], &v_block, &de) != 5092 DW_DLV_OK) { 5093 warnx("dwarf_formblock failed: %s", 5094 dwarf_errmsg(de)); 5095 continue; 5096 } 5097 printf("%ju byte block:", (uintmax_t) v_block->bl_len); 5098 b = v_block->bl_data; 5099 for (j = 0; (Dwarf_Unsigned) j < v_block->bl_len; j++) 5100 printf(" %x", b[j]); 5101 printf("\t("); 5102 dump_dwarf_block(re, v_block->bl_data, v_block->bl_len); 5103 putchar(')'); 5104 break; 5105 5106 case DW_FORM_exprloc: 5107 if (dwarf_formexprloc(attr_list[i], &v_udata, &v_expr, 5108 &de) != DW_DLV_OK) { 5109 warnx("dwarf_formexprloc failed: %s", 5110 dwarf_errmsg(de)); 5111 continue; 5112 } 5113 printf("%ju byte block:", (uintmax_t) v_udata); 5114 b = v_expr; 5115 for (j = 0; (Dwarf_Unsigned) j < v_udata; j++) 5116 printf(" %x", b[j]); 5117 printf("\t("); 5118 dump_dwarf_block(re, v_expr, v_udata); 5119 putchar(')'); 5120 break; 5121 5122 case DW_FORM_ref_sig8: 5123 if (dwarf_formsig8(attr_list[i], &v_sig8, &de) != 5124 DW_DLV_OK) { 5125 warnx("dwarf_formsig8 failed: %s", 5126 dwarf_errmsg(de)); 5127 continue; 5128 } 5129 p = (uint8_t *)(uintptr_t) &v_sig8.signature[0]; 5130 v_sig = re->dw_decode(&p, 8); 5131 printf("signature: 0x%jx", (uintmax_t) v_sig); 5132 } 5133 switch (attr) { 5134 case DW_AT_encoding: 5135 if (dwarf_attrval_unsigned(die, attr, &ate, &de) != 5136 DW_DLV_OK) 5137 break; 5138 if (dwarf_get_ATE_name(ate, &ate_str) != DW_DLV_OK) 5139 ate_str = "DW_ATE_UNKNOWN"; 5140 printf("\t(%s)", &ate_str[strlen("DW_ATE_")]); 5141 break; 5142 5143 case DW_AT_language: 5144 if (dwarf_attrval_unsigned(die, attr, &lang, &de) != 5145 DW_DLV_OK) 5146 break; 5147 if (dwarf_get_LANG_name(lang, &lang_str) != DW_DLV_OK) 5148 break; 5149 printf("\t(%s)", &lang_str[strlen("DW_LANG_")]); 5150 break; 5151 5152 case DW_AT_location: 5153 case DW_AT_string_length: 5154 case DW_AT_return_addr: 5155 case DW_AT_data_member_location: 5156 case DW_AT_frame_base: 5157 case DW_AT_segment: 5158 case DW_AT_static_link: 5159 case DW_AT_use_location: 5160 case DW_AT_vtable_elem_location: 5161 switch (form) { 5162 case DW_FORM_data4: 5163 case DW_FORM_data8: 5164 case DW_FORM_sec_offset: 5165 printf("\t(location list)"); 5166 break; 5167 default: 5168 break; 5169 } 5170 5171 default: 5172 break; 5173 } 5174 putchar('\n'); 5175 } 5176 5177 5178 cont_search: 5179 /* Search children. */ 5180 ret = dwarf_child(die, &ret_die, &de); 5181 if (ret == DW_DLV_ERROR) 5182 warnx("dwarf_child: %s", dwarf_errmsg(de)); 5183 else if (ret == DW_DLV_OK) 5184 dump_dwarf_die(re, ret_die, level + 1); 5185 5186 /* Search sibling. */ 5187 is_info = dwarf_get_die_infotypes_flag(die); 5188 ret = dwarf_siblingof_b(re->dbg, die, &ret_die, is_info, &de); 5189 if (ret == DW_DLV_ERROR) 5190 warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); 5191 else if (ret == DW_DLV_OK) 5192 dump_dwarf_die(re, ret_die, level); 5193 5194 dwarf_dealloc(re->dbg, die, DW_DLA_DIE); 5195 } 5196 5197 static void 5198 set_cu_context(struct readelf *re, Dwarf_Half psize, Dwarf_Half osize, 5199 Dwarf_Half ver) 5200 { 5201 5202 re->cu_psize = psize; 5203 re->cu_osize = osize; 5204 re->cu_ver = ver; 5205 } 5206 5207 static void 5208 dump_dwarf_info(struct readelf *re, Dwarf_Bool is_info) 5209 { 5210 struct section *s; 5211 Dwarf_Die die; 5212 Dwarf_Error de; 5213 Dwarf_Half tag, version, pointer_size, off_size; 5214 Dwarf_Off cu_offset, cu_length; 5215 Dwarf_Off aboff; 5216 Dwarf_Unsigned typeoff; 5217 Dwarf_Sig8 sig8; 5218 Dwarf_Unsigned sig; 5219 uint8_t *p; 5220 const char *sn; 5221 int i, ret; 5222 5223 sn = is_info ? ".debug_info" : ".debug_types"; 5224 5225 s = NULL; 5226 for (i = 0; (size_t) i < re->shnum; i++) { 5227 s = &re->sl[i]; 5228 if (s->name != NULL && !strcmp(s->name, sn)) 5229 break; 5230 } 5231 if ((size_t) i >= re->shnum) 5232 return; 5233 5234 do { 5235 printf("\nDump of debug contents of section %s:\n", sn); 5236 5237 while ((ret = dwarf_next_cu_header_c(re->dbg, is_info, NULL, 5238 &version, &aboff, &pointer_size, &off_size, NULL, &sig8, 5239 &typeoff, NULL, &de)) == DW_DLV_OK) { 5240 set_cu_context(re, pointer_size, off_size, version); 5241 die = NULL; 5242 while (dwarf_siblingof_b(re->dbg, die, &die, is_info, 5243 &de) == DW_DLV_OK) { 5244 if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { 5245 warnx("dwarf_tag failed: %s", 5246 dwarf_errmsg(de)); 5247 continue; 5248 } 5249 /* XXX: What about DW_TAG_partial_unit? */ 5250 if ((is_info && tag == DW_TAG_compile_unit) || 5251 (!is_info && tag == DW_TAG_type_unit)) 5252 break; 5253 } 5254 if (die == NULL && is_info) { 5255 warnx("could not find DW_TAG_compile_unit " 5256 "die"); 5257 continue; 5258 } else if (die == NULL && !is_info) { 5259 warnx("could not find DW_TAG_type_unit die"); 5260 continue; 5261 } 5262 5263 if (dwarf_die_CU_offset_range(die, &cu_offset, 5264 &cu_length, &de) != DW_DLV_OK) { 5265 warnx("dwarf_die_CU_offset failed: %s", 5266 dwarf_errmsg(de)); 5267 continue; 5268 } 5269 5270 cu_length -= off_size == 4 ? 4 : 12; 5271 5272 sig = 0; 5273 if (!is_info) { 5274 p = (uint8_t *)(uintptr_t) &sig8.signature[0]; 5275 sig = re->dw_decode(&p, 8); 5276 } 5277 5278 printf("\n Type Unit @ offset 0x%jx:\n", 5279 (uintmax_t) cu_offset); 5280 printf(" Length:\t\t%#jx (%d-bit)\n", 5281 (uintmax_t) cu_length, off_size == 4 ? 32 : 64); 5282 printf(" Version:\t\t%u\n", version); 5283 printf(" Abbrev Offset:\t0x%jx\n", 5284 (uintmax_t) aboff); 5285 printf(" Pointer Size:\t%u\n", pointer_size); 5286 if (!is_info) { 5287 printf(" Signature:\t\t0x%016jx\n", 5288 (uintmax_t) sig); 5289 printf(" Type Offset:\t0x%jx\n", 5290 (uintmax_t) typeoff); 5291 } 5292 5293 dump_dwarf_die(re, die, 0); 5294 } 5295 if (ret == DW_DLV_ERROR) 5296 warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); 5297 if (is_info) 5298 break; 5299 } while (dwarf_next_types_section(re->dbg, &de) == DW_DLV_OK); 5300 } 5301 5302 static void 5303 dump_dwarf_abbrev(struct readelf *re) 5304 { 5305 Dwarf_Abbrev ab; 5306 Dwarf_Off aboff, atoff; 5307 Dwarf_Unsigned length, attr_count; 5308 Dwarf_Signed flag, form; 5309 Dwarf_Half tag, attr; 5310 Dwarf_Error de; 5311 const char *tag_str, *attr_str, *form_str; 5312 char unk_tag[32], unk_attr[32], unk_form[32]; 5313 int i, j, ret; 5314 5315 printf("\nContents of section .debug_abbrev:\n\n"); 5316 5317 while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, &aboff, 5318 NULL, NULL, &de)) == DW_DLV_OK) { 5319 printf(" Number TAG\n"); 5320 i = 0; 5321 while ((ret = dwarf_get_abbrev(re->dbg, aboff, &ab, &length, 5322 &attr_count, &de)) == DW_DLV_OK) { 5323 if (length == 1) { 5324 dwarf_dealloc(re->dbg, ab, DW_DLA_ABBREV); 5325 break; 5326 } 5327 aboff += length; 5328 printf("%4d", ++i); 5329 if (dwarf_get_abbrev_tag(ab, &tag, &de) != DW_DLV_OK) { 5330 warnx("dwarf_get_abbrev_tag failed: %s", 5331 dwarf_errmsg(de)); 5332 goto next_abbrev; 5333 } 5334 if (dwarf_get_TAG_name(tag, &tag_str) != DW_DLV_OK) { 5335 snprintf(unk_tag, sizeof(unk_tag), 5336 "[Unknown Tag: %#x]", tag); 5337 tag_str = unk_tag; 5338 } 5339 if (dwarf_get_abbrev_children_flag(ab, &flag, &de) != 5340 DW_DLV_OK) { 5341 warnx("dwarf_get_abbrev_children_flag failed:" 5342 " %s", dwarf_errmsg(de)); 5343 goto next_abbrev; 5344 } 5345 printf(" %s %s\n", tag_str, 5346 flag ? "[has children]" : "[no children]"); 5347 for (j = 0; (Dwarf_Unsigned) j < attr_count; j++) { 5348 if (dwarf_get_abbrev_entry(ab, (Dwarf_Signed) j, 5349 &attr, &form, &atoff, &de) != DW_DLV_OK) { 5350 warnx("dwarf_get_abbrev_entry failed:" 5351 " %s", dwarf_errmsg(de)); 5352 continue; 5353 } 5354 if (dwarf_get_AT_name(attr, &attr_str) != 5355 DW_DLV_OK) { 5356 snprintf(unk_attr, sizeof(unk_attr), 5357 "[Unknown AT: %#x]", attr); 5358 attr_str = unk_attr; 5359 } 5360 if (dwarf_get_FORM_name(form, &form_str) != 5361 DW_DLV_OK) { 5362 snprintf(unk_form, sizeof(unk_form), 5363 "[Unknown Form: %#x]", 5364 (Dwarf_Half) form); 5365 form_str = unk_form; 5366 } 5367 printf(" %-18s %s\n", attr_str, form_str); 5368 } 5369 next_abbrev: 5370 dwarf_dealloc(re->dbg, ab, DW_DLA_ABBREV); 5371 } 5372 if (ret != DW_DLV_OK) 5373 warnx("dwarf_get_abbrev: %s", dwarf_errmsg(de)); 5374 } 5375 if (ret == DW_DLV_ERROR) 5376 warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); 5377 } 5378 5379 static void 5380 dump_dwarf_pubnames(struct readelf *re) 5381 { 5382 struct section *s; 5383 Dwarf_Off die_off; 5384 Dwarf_Unsigned offset, length, nt_cu_offset, nt_cu_length; 5385 Dwarf_Signed cnt; 5386 Dwarf_Global *globs; 5387 Dwarf_Half nt_version; 5388 Dwarf_Error de; 5389 Elf_Data *d; 5390 char *glob_name; 5391 int i, dwarf_size, elferr; 5392 5393 printf("\nContents of the .debug_pubnames section:\n"); 5394 5395 s = NULL; 5396 for (i = 0; (size_t) i < re->shnum; i++) { 5397 s = &re->sl[i]; 5398 if (s->name != NULL && !strcmp(s->name, ".debug_pubnames")) 5399 break; 5400 } 5401 if ((size_t) i >= re->shnum) 5402 return; 5403 5404 (void) elf_errno(); 5405 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 5406 elferr = elf_errno(); 5407 if (elferr != 0) 5408 warnx("elf_getdata failed: %s", elf_errmsg(-1)); 5409 return; 5410 } 5411 if (d->d_size <= 0) 5412 return; 5413 5414 /* Read in .debug_pubnames section table header. */ 5415 offset = 0; 5416 length = re->dw_read(d, &offset, 4); 5417 if (length == 0xffffffff) { 5418 dwarf_size = 8; 5419 length = re->dw_read(d, &offset, 8); 5420 } else 5421 dwarf_size = 4; 5422 5423 if (length > d->d_size - offset) { 5424 warnx("invalid .dwarf_pubnames section"); 5425 return; 5426 } 5427 5428 nt_version = re->dw_read(d, &offset, 2); 5429 nt_cu_offset = re->dw_read(d, &offset, dwarf_size); 5430 nt_cu_length = re->dw_read(d, &offset, dwarf_size); 5431 printf(" Length:\t\t\t\t%ju\n", (uintmax_t) length); 5432 printf(" Version:\t\t\t\t%u\n", nt_version); 5433 printf(" Offset into .debug_info section:\t%ju\n", 5434 (uintmax_t) nt_cu_offset); 5435 printf(" Size of area in .debug_info section:\t%ju\n", 5436 (uintmax_t) nt_cu_length); 5437 5438 if (dwarf_get_globals(re->dbg, &globs, &cnt, &de) != DW_DLV_OK) { 5439 warnx("dwarf_get_globals failed: %s", dwarf_errmsg(de)); 5440 return; 5441 } 5442 5443 printf("\n Offset Name\n"); 5444 for (i = 0; i < cnt; i++) { 5445 if (dwarf_globname(globs[i], &glob_name, &de) != DW_DLV_OK) { 5446 warnx("dwarf_globname failed: %s", dwarf_errmsg(de)); 5447 continue; 5448 } 5449 if (dwarf_global_die_offset(globs[i], &die_off, &de) != 5450 DW_DLV_OK) { 5451 warnx("dwarf_global_die_offset failed: %s", 5452 dwarf_errmsg(de)); 5453 continue; 5454 } 5455 printf(" %-11ju %s\n", (uintmax_t) die_off, glob_name); 5456 } 5457 } 5458 5459 static void 5460 dump_dwarf_aranges(struct readelf *re) 5461 { 5462 struct section *s; 5463 Dwarf_Arange *aranges; 5464 Dwarf_Addr start; 5465 Dwarf_Unsigned offset, length, as_cu_offset; 5466 Dwarf_Off die_off; 5467 Dwarf_Signed cnt; 5468 Dwarf_Half as_version, as_addrsz, as_segsz; 5469 Dwarf_Error de; 5470 Elf_Data *d; 5471 int i, dwarf_size, elferr; 5472 5473 printf("\nContents of section .debug_aranges:\n"); 5474 5475 s = NULL; 5476 for (i = 0; (size_t) i < re->shnum; i++) { 5477 s = &re->sl[i]; 5478 if (s->name != NULL && !strcmp(s->name, ".debug_aranges")) 5479 break; 5480 } 5481 if ((size_t) i >= re->shnum) 5482 return; 5483 5484 (void) elf_errno(); 5485 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 5486 elferr = elf_errno(); 5487 if (elferr != 0) 5488 warnx("elf_getdata failed: %s", elf_errmsg(-1)); 5489 return; 5490 } 5491 if (d->d_size <= 0) 5492 return; 5493 5494 /* Read in the .debug_aranges section table header. */ 5495 offset = 0; 5496 length = re->dw_read(d, &offset, 4); 5497 if (length == 0xffffffff) { 5498 dwarf_size = 8; 5499 length = re->dw_read(d, &offset, 8); 5500 } else 5501 dwarf_size = 4; 5502 5503 if (length > d->d_size - offset) { 5504 warnx("invalid .dwarf_aranges section"); 5505 return; 5506 } 5507 5508 as_version = re->dw_read(d, &offset, 2); 5509 as_cu_offset = re->dw_read(d, &offset, dwarf_size); 5510 as_addrsz = re->dw_read(d, &offset, 1); 5511 as_segsz = re->dw_read(d, &offset, 1); 5512 5513 printf(" Length:\t\t\t%ju\n", (uintmax_t) length); 5514 printf(" Version:\t\t\t%u\n", as_version); 5515 printf(" Offset into .debug_info:\t%ju\n", (uintmax_t) as_cu_offset); 5516 printf(" Pointer Size:\t\t\t%u\n", as_addrsz); 5517 printf(" Segment Size:\t\t\t%u\n", as_segsz); 5518 5519 if (dwarf_get_aranges(re->dbg, &aranges, &cnt, &de) != DW_DLV_OK) { 5520 warnx("dwarf_get_aranges failed: %s", dwarf_errmsg(de)); 5521 return; 5522 } 5523 5524 printf("\n Address Length\n"); 5525 for (i = 0; i < cnt; i++) { 5526 if (dwarf_get_arange_info(aranges[i], &start, &length, 5527 &die_off, &de) != DW_DLV_OK) { 5528 warnx("dwarf_get_arange_info failed: %s", 5529 dwarf_errmsg(de)); 5530 continue; 5531 } 5532 printf(" %08jx %ju\n", (uintmax_t) start, 5533 (uintmax_t) length); 5534 } 5535 } 5536 5537 static void 5538 dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die, Dwarf_Addr base) 5539 { 5540 Dwarf_Attribute *attr_list; 5541 Dwarf_Ranges *ranges; 5542 Dwarf_Die ret_die; 5543 Dwarf_Error de; 5544 Dwarf_Addr base0; 5545 Dwarf_Half attr; 5546 Dwarf_Signed attr_count, cnt; 5547 Dwarf_Unsigned off, bytecnt; 5548 int i, j, ret; 5549 5550 if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != 5551 DW_DLV_OK) { 5552 if (ret == DW_DLV_ERROR) 5553 warnx("dwarf_attrlist failed: %s", dwarf_errmsg(de)); 5554 goto cont_search; 5555 } 5556 5557 for (i = 0; i < attr_count; i++) { 5558 if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { 5559 warnx("dwarf_whatattr failed: %s", dwarf_errmsg(de)); 5560 continue; 5561 } 5562 if (attr != DW_AT_ranges) 5563 continue; 5564 if (dwarf_formudata(attr_list[i], &off, &de) != DW_DLV_OK) { 5565 warnx("dwarf_formudata failed: %s", dwarf_errmsg(de)); 5566 continue; 5567 } 5568 if (dwarf_get_ranges(re->dbg, (Dwarf_Off) off, &ranges, &cnt, 5569 &bytecnt, &de) != DW_DLV_OK) 5570 continue; 5571 base0 = base; 5572 for (j = 0; j < cnt; j++) { 5573 printf(" %08jx ", (uintmax_t) off); 5574 if (ranges[j].dwr_type == DW_RANGES_END) { 5575 printf("%s\n", "<End of list>"); 5576 continue; 5577 } else if (ranges[j].dwr_type == 5578 DW_RANGES_ADDRESS_SELECTION) { 5579 base0 = ranges[j].dwr_addr2; 5580 continue; 5581 } 5582 if (re->ec == ELFCLASS32) 5583 printf("%08jx %08jx\n", 5584 ranges[j].dwr_addr1 + base0, 5585 ranges[j].dwr_addr2 + base0); 5586 else 5587 printf("%016jx %016jx\n", 5588 ranges[j].dwr_addr1 + base0, 5589 ranges[j].dwr_addr2 + base0); 5590 } 5591 } 5592 5593 cont_search: 5594 /* Search children. */ 5595 ret = dwarf_child(die, &ret_die, &de); 5596 if (ret == DW_DLV_ERROR) 5597 warnx("dwarf_child: %s", dwarf_errmsg(de)); 5598 else if (ret == DW_DLV_OK) 5599 dump_dwarf_ranges_foreach(re, ret_die, base); 5600 5601 /* Search sibling. */ 5602 ret = dwarf_siblingof(re->dbg, die, &ret_die, &de); 5603 if (ret == DW_DLV_ERROR) 5604 warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); 5605 else if (ret == DW_DLV_OK) 5606 dump_dwarf_ranges_foreach(re, ret_die, base); 5607 } 5608 5609 static void 5610 dump_dwarf_ranges(struct readelf *re) 5611 { 5612 Dwarf_Ranges *ranges; 5613 Dwarf_Die die; 5614 Dwarf_Signed cnt; 5615 Dwarf_Unsigned bytecnt; 5616 Dwarf_Half tag; 5617 Dwarf_Error de; 5618 Dwarf_Unsigned lowpc; 5619 int ret; 5620 5621 if (dwarf_get_ranges(re->dbg, 0, &ranges, &cnt, &bytecnt, &de) != 5622 DW_DLV_OK) 5623 return; 5624 5625 printf("Contents of the .debug_ranges section:\n\n"); 5626 if (re->ec == ELFCLASS32) 5627 printf(" %-8s %-8s %s\n", "Offset", "Begin", "End"); 5628 else 5629 printf(" %-8s %-16s %s\n", "Offset", "Begin", "End"); 5630 5631 while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, NULL, NULL, 5632 NULL, &de)) == DW_DLV_OK) { 5633 die = NULL; 5634 if (dwarf_siblingof(re->dbg, die, &die, &de) != DW_DLV_OK) 5635 continue; 5636 if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { 5637 warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); 5638 continue; 5639 } 5640 /* XXX: What about DW_TAG_partial_unit? */ 5641 lowpc = 0; 5642 if (tag == DW_TAG_compile_unit) { 5643 if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lowpc, 5644 &de) != DW_DLV_OK) 5645 lowpc = 0; 5646 } 5647 5648 dump_dwarf_ranges_foreach(re, die, (Dwarf_Addr) lowpc); 5649 } 5650 putchar('\n'); 5651 } 5652 5653 static void 5654 dump_dwarf_macinfo(struct readelf *re) 5655 { 5656 Dwarf_Unsigned offset; 5657 Dwarf_Signed cnt; 5658 Dwarf_Macro_Details *md; 5659 Dwarf_Error de; 5660 const char *mi_str; 5661 char unk_mi[32]; 5662 int i; 5663 5664 #define _MAX_MACINFO_ENTRY 65535 5665 5666 printf("\nContents of section .debug_macinfo:\n\n"); 5667 5668 offset = 0; 5669 while (dwarf_get_macro_details(re->dbg, offset, _MAX_MACINFO_ENTRY, 5670 &cnt, &md, &de) == DW_DLV_OK) { 5671 for (i = 0; i < cnt; i++) { 5672 offset = md[i].dmd_offset + 1; 5673 if (md[i].dmd_type == 0) 5674 break; 5675 if (dwarf_get_MACINFO_name(md[i].dmd_type, &mi_str) != 5676 DW_DLV_OK) { 5677 snprintf(unk_mi, sizeof(unk_mi), 5678 "[Unknown MACINFO: %#x]", md[i].dmd_type); 5679 mi_str = unk_mi; 5680 } 5681 printf(" %s", mi_str); 5682 switch (md[i].dmd_type) { 5683 case DW_MACINFO_define: 5684 case DW_MACINFO_undef: 5685 printf(" - lineno : %jd macro : %s\n", 5686 (intmax_t) md[i].dmd_lineno, 5687 md[i].dmd_macro); 5688 break; 5689 case DW_MACINFO_start_file: 5690 printf(" - lineno : %jd filenum : %jd\n", 5691 (intmax_t) md[i].dmd_lineno, 5692 (intmax_t) md[i].dmd_fileindex); 5693 break; 5694 default: 5695 putchar('\n'); 5696 break; 5697 } 5698 } 5699 } 5700 5701 #undef _MAX_MACINFO_ENTRY 5702 } 5703 5704 static void 5705 dump_dwarf_frame_inst(struct readelf *re, Dwarf_Cie cie, uint8_t *insts, 5706 Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, Dwarf_Addr pc, 5707 Dwarf_Debug dbg) 5708 { 5709 Dwarf_Frame_Op *oplist; 5710 Dwarf_Signed opcnt, delta; 5711 Dwarf_Small op; 5712 Dwarf_Error de; 5713 const char *op_str; 5714 char unk_op[32]; 5715 int i; 5716 5717 if (dwarf_expand_frame_instructions(cie, insts, len, &oplist, 5718 &opcnt, &de) != DW_DLV_OK) { 5719 warnx("dwarf_expand_frame_instructions failed: %s", 5720 dwarf_errmsg(de)); 5721 return; 5722 } 5723 5724 for (i = 0; i < opcnt; i++) { 5725 if (oplist[i].fp_base_op != 0) 5726 op = oplist[i].fp_base_op << 6; 5727 else 5728 op = oplist[i].fp_extended_op; 5729 if (dwarf_get_CFA_name(op, &op_str) != DW_DLV_OK) { 5730 snprintf(unk_op, sizeof(unk_op), "[Unknown CFA: %#x]", 5731 op); 5732 op_str = unk_op; 5733 } 5734 printf(" %s", op_str); 5735 switch (op) { 5736 case DW_CFA_advance_loc: 5737 delta = oplist[i].fp_offset * caf; 5738 pc += delta; 5739 printf(": %ju to %08jx", (uintmax_t) delta, 5740 (uintmax_t) pc); 5741 break; 5742 case DW_CFA_offset: 5743 case DW_CFA_offset_extended: 5744 case DW_CFA_offset_extended_sf: 5745 delta = oplist[i].fp_offset * daf; 5746 printf(": r%u (%s) at cfa%+jd", oplist[i].fp_register, 5747 dwarf_regname(re, oplist[i].fp_register), 5748 (intmax_t) delta); 5749 break; 5750 case DW_CFA_restore: 5751 printf(": r%u (%s)", oplist[i].fp_register, 5752 dwarf_regname(re, oplist[i].fp_register)); 5753 break; 5754 case DW_CFA_set_loc: 5755 pc = oplist[i].fp_offset; 5756 printf(": to %08jx", (uintmax_t) pc); 5757 break; 5758 case DW_CFA_advance_loc1: 5759 case DW_CFA_advance_loc2: 5760 case DW_CFA_advance_loc4: 5761 pc += oplist[i].fp_offset; 5762 printf(": %jd to %08jx", (intmax_t) oplist[i].fp_offset, 5763 (uintmax_t) pc); 5764 break; 5765 case DW_CFA_def_cfa: 5766 printf(": r%u (%s) ofs %ju", oplist[i].fp_register, 5767 dwarf_regname(re, oplist[i].fp_register), 5768 (uintmax_t) oplist[i].fp_offset); 5769 break; 5770 case DW_CFA_def_cfa_sf: 5771 printf(": r%u (%s) ofs %jd", oplist[i].fp_register, 5772 dwarf_regname(re, oplist[i].fp_register), 5773 (intmax_t) (oplist[i].fp_offset * daf)); 5774 break; 5775 case DW_CFA_def_cfa_register: 5776 printf(": r%u (%s)", oplist[i].fp_register, 5777 dwarf_regname(re, oplist[i].fp_register)); 5778 break; 5779 case DW_CFA_def_cfa_offset: 5780 printf(": %ju", (uintmax_t) oplist[i].fp_offset); 5781 break; 5782 case DW_CFA_def_cfa_offset_sf: 5783 printf(": %jd", (intmax_t) (oplist[i].fp_offset * daf)); 5784 break; 5785 default: 5786 break; 5787 } 5788 putchar('\n'); 5789 } 5790 5791 dwarf_dealloc(dbg, oplist, DW_DLA_FRAME_BLOCK); 5792 } 5793 5794 static char * 5795 get_regoff_str(struct readelf *re, Dwarf_Half reg, Dwarf_Addr off) 5796 { 5797 static char rs[16]; 5798 5799 if (reg == DW_FRAME_UNDEFINED_VAL || reg == DW_FRAME_REG_INITIAL_VALUE) 5800 snprintf(rs, sizeof(rs), "%c", 'u'); 5801 else if (reg == DW_FRAME_CFA_COL) 5802 snprintf(rs, sizeof(rs), "c%+jd", (intmax_t) off); 5803 else 5804 snprintf(rs, sizeof(rs), "%s%+jd", dwarf_regname(re, reg), 5805 (intmax_t) off); 5806 5807 return (rs); 5808 } 5809 5810 static int 5811 dump_dwarf_frame_regtable(struct readelf *re, Dwarf_Fde fde, Dwarf_Addr pc, 5812 Dwarf_Unsigned func_len, Dwarf_Half cie_ra) 5813 { 5814 Dwarf_Regtable rt; 5815 Dwarf_Addr row_pc, end_pc, pre_pc, cur_pc; 5816 Dwarf_Error de; 5817 char *vec; 5818 int i; 5819 5820 #define BIT_SET(v, n) (v[(n)>>3] |= 1U << ((n) & 7)) 5821 #define BIT_CLR(v, n) (v[(n)>>3] &= ~(1U << ((n) & 7))) 5822 #define BIT_ISSET(v, n) (v[(n)>>3] & (1U << ((n) & 7))) 5823 #define RT(x) rt.rules[(x)] 5824 5825 vec = calloc((DW_REG_TABLE_SIZE + 7) / 8, 1); 5826 if (vec == NULL) 5827 err(EXIT_FAILURE, "calloc failed"); 5828 5829 pre_pc = ~((Dwarf_Addr) 0); 5830 cur_pc = pc; 5831 end_pc = pc + func_len; 5832 for (; cur_pc < end_pc; cur_pc++) { 5833 if (dwarf_get_fde_info_for_all_regs(fde, cur_pc, &rt, &row_pc, 5834 &de) != DW_DLV_OK) { 5835 warnx("dwarf_get_fde_info_for_all_regs failed: %s\n", 5836 dwarf_errmsg(de)); 5837 return (-1); 5838 } 5839 if (row_pc == pre_pc) 5840 continue; 5841 pre_pc = row_pc; 5842 for (i = 1; i < DW_REG_TABLE_SIZE; i++) { 5843 if (rt.rules[i].dw_regnum != DW_FRAME_REG_INITIAL_VALUE) 5844 BIT_SET(vec, i); 5845 } 5846 } 5847 5848 printf(" LOC CFA "); 5849 for (i = 1; i < DW_REG_TABLE_SIZE; i++) { 5850 if (BIT_ISSET(vec, i)) { 5851 if ((Dwarf_Half) i == cie_ra) 5852 printf("ra "); 5853 else 5854 printf("%-5s", 5855 dwarf_regname(re, (unsigned int) i)); 5856 } 5857 } 5858 putchar('\n'); 5859 5860 pre_pc = ~((Dwarf_Addr) 0); 5861 cur_pc = pc; 5862 end_pc = pc + func_len; 5863 for (; cur_pc < end_pc; cur_pc++) { 5864 if (dwarf_get_fde_info_for_all_regs(fde, cur_pc, &rt, &row_pc, 5865 &de) != DW_DLV_OK) { 5866 warnx("dwarf_get_fde_info_for_all_regs failed: %s\n", 5867 dwarf_errmsg(de)); 5868 return (-1); 5869 } 5870 if (row_pc == pre_pc) 5871 continue; 5872 pre_pc = row_pc; 5873 printf("%08jx ", (uintmax_t) row_pc); 5874 printf("%-8s ", get_regoff_str(re, RT(0).dw_regnum, 5875 RT(0).dw_offset)); 5876 for (i = 1; i < DW_REG_TABLE_SIZE; i++) { 5877 if (BIT_ISSET(vec, i)) { 5878 printf("%-5s", get_regoff_str(re, 5879 RT(i).dw_regnum, RT(i).dw_offset)); 5880 } 5881 } 5882 putchar('\n'); 5883 } 5884 5885 free(vec); 5886 5887 return (0); 5888 5889 #undef BIT_SET 5890 #undef BIT_CLR 5891 #undef BIT_ISSET 5892 #undef RT 5893 } 5894 5895 static void 5896 dump_dwarf_frame_section(struct readelf *re, struct section *s, int alt) 5897 { 5898 Dwarf_Cie *cie_list, cie, pre_cie; 5899 Dwarf_Fde *fde_list, fde; 5900 Dwarf_Off cie_offset, fde_offset; 5901 Dwarf_Unsigned cie_length, fde_instlen; 5902 Dwarf_Unsigned cie_caf, cie_daf, cie_instlen, func_len, fde_length; 5903 Dwarf_Signed cie_count, fde_count, cie_index; 5904 Dwarf_Addr low_pc; 5905 Dwarf_Half cie_ra; 5906 Dwarf_Small cie_version; 5907 Dwarf_Ptr fde_addr, fde_inst, cie_inst; 5908 char *cie_aug, c; 5909 int i, eh_frame; 5910 Dwarf_Error de; 5911 5912 printf("\nThe section %s contains:\n\n", s->name); 5913 5914 if (!strcmp(s->name, ".debug_frame")) { 5915 eh_frame = 0; 5916 if (dwarf_get_fde_list(re->dbg, &cie_list, &cie_count, 5917 &fde_list, &fde_count, &de) != DW_DLV_OK) { 5918 warnx("dwarf_get_fde_list failed: %s", 5919 dwarf_errmsg(de)); 5920 return; 5921 } 5922 } else if (!strcmp(s->name, ".eh_frame")) { 5923 eh_frame = 1; 5924 if (dwarf_get_fde_list_eh(re->dbg, &cie_list, &cie_count, 5925 &fde_list, &fde_count, &de) != DW_DLV_OK) { 5926 warnx("dwarf_get_fde_list_eh failed: %s", 5927 dwarf_errmsg(de)); 5928 return; 5929 } 5930 } else 5931 return; 5932 5933 pre_cie = NULL; 5934 for (i = 0; i < fde_count; i++) { 5935 if (dwarf_get_fde_n(fde_list, i, &fde, &de) != DW_DLV_OK) { 5936 warnx("dwarf_get_fde_n failed: %s", dwarf_errmsg(de)); 5937 continue; 5938 } 5939 if (dwarf_get_cie_of_fde(fde, &cie, &de) != DW_DLV_OK) { 5940 warnx("dwarf_get_fde_n failed: %s", dwarf_errmsg(de)); 5941 continue; 5942 } 5943 if (dwarf_get_fde_range(fde, &low_pc, &func_len, &fde_addr, 5944 &fde_length, &cie_offset, &cie_index, &fde_offset, 5945 &de) != DW_DLV_OK) { 5946 warnx("dwarf_get_fde_range failed: %s", 5947 dwarf_errmsg(de)); 5948 continue; 5949 } 5950 if (dwarf_get_fde_instr_bytes(fde, &fde_inst, &fde_instlen, 5951 &de) != DW_DLV_OK) { 5952 warnx("dwarf_get_fde_instr_bytes failed: %s", 5953 dwarf_errmsg(de)); 5954 continue; 5955 } 5956 if (pre_cie == NULL || cie != pre_cie) { 5957 pre_cie = cie; 5958 if (dwarf_get_cie_info(cie, &cie_length, &cie_version, 5959 &cie_aug, &cie_caf, &cie_daf, &cie_ra, 5960 &cie_inst, &cie_instlen, &de) != DW_DLV_OK) { 5961 warnx("dwarf_get_cie_info failed: %s", 5962 dwarf_errmsg(de)); 5963 continue; 5964 } 5965 printf("%08jx %08jx %8.8jx CIE", 5966 (uintmax_t) cie_offset, 5967 (uintmax_t) cie_length, 5968 (uintmax_t) (eh_frame ? 0 : ~0U)); 5969 if (!alt) { 5970 putchar('\n'); 5971 printf(" Version:\t\t\t%u\n", cie_version); 5972 printf(" Augmentation:\t\t\t\""); 5973 while ((c = *cie_aug++) != '\0') 5974 putchar(c); 5975 printf("\"\n"); 5976 printf(" Code alignment factor:\t%ju\n", 5977 (uintmax_t) cie_caf); 5978 printf(" Data alignment factor:\t%jd\n", 5979 (intmax_t) cie_daf); 5980 printf(" Return address column:\t%ju\n", 5981 (uintmax_t) cie_ra); 5982 putchar('\n'); 5983 dump_dwarf_frame_inst(re, cie, cie_inst, 5984 cie_instlen, cie_caf, cie_daf, 0, 5985 re->dbg); 5986 putchar('\n'); 5987 } else { 5988 printf(" \""); 5989 while ((c = *cie_aug++) != '\0') 5990 putchar(c); 5991 putchar('"'); 5992 printf(" cf=%ju df=%jd ra=%ju\n", 5993 (uintmax_t) cie_caf, 5994 (uintmax_t) cie_daf, 5995 (uintmax_t) cie_ra); 5996 dump_dwarf_frame_regtable(re, fde, low_pc, 1, 5997 cie_ra); 5998 putchar('\n'); 5999 } 6000 } 6001 printf("%08jx %08jx %08jx FDE cie=%08jx pc=%08jx..%08jx\n", 6002 (uintmax_t) fde_offset, (uintmax_t) fde_length, 6003 (uintmax_t) cie_offset, 6004 (uintmax_t) (eh_frame ? fde_offset + 4 - cie_offset : 6005 cie_offset), 6006 (uintmax_t) low_pc, (uintmax_t) (low_pc + func_len)); 6007 if (!alt) 6008 dump_dwarf_frame_inst(re, cie, fde_inst, fde_instlen, 6009 cie_caf, cie_daf, low_pc, re->dbg); 6010 else 6011 dump_dwarf_frame_regtable(re, fde, low_pc, func_len, 6012 cie_ra); 6013 putchar('\n'); 6014 } 6015 } 6016 6017 static void 6018 dump_dwarf_frame(struct readelf *re, int alt) 6019 { 6020 struct section *s; 6021 int i; 6022 6023 (void) dwarf_set_frame_cfa_value(re->dbg, DW_FRAME_CFA_COL); 6024 6025 for (i = 0; (size_t) i < re->shnum; i++) { 6026 s = &re->sl[i]; 6027 if (s->name != NULL && (!strcmp(s->name, ".debug_frame") || 6028 !strcmp(s->name, ".eh_frame"))) 6029 dump_dwarf_frame_section(re, s, alt); 6030 } 6031 } 6032 6033 static void 6034 dump_dwarf_str(struct readelf *re) 6035 { 6036 struct section *s; 6037 Elf_Data *d; 6038 unsigned char *p; 6039 int elferr, end, i, j; 6040 6041 printf("\nContents of section .debug_str:\n"); 6042 6043 s = NULL; 6044 for (i = 0; (size_t) i < re->shnum; i++) { 6045 s = &re->sl[i]; 6046 if (s->name != NULL && !strcmp(s->name, ".debug_str")) 6047 break; 6048 } 6049 if ((size_t) i >= re->shnum) 6050 return; 6051 6052 (void) elf_errno(); 6053 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 6054 elferr = elf_errno(); 6055 if (elferr != 0) 6056 warnx("elf_getdata failed: %s", elf_errmsg(-1)); 6057 return; 6058 } 6059 if (d->d_size <= 0) 6060 return; 6061 6062 for (i = 0, p = d->d_buf; (size_t) i < d->d_size; i += 16) { 6063 printf(" 0x%08x", (unsigned int) i); 6064 if ((size_t) i + 16 > d->d_size) 6065 end = d->d_size; 6066 else 6067 end = i + 16; 6068 for (j = i; j < i + 16; j++) { 6069 if ((j - i) % 4 == 0) 6070 putchar(' '); 6071 if (j >= end) { 6072 printf(" "); 6073 continue; 6074 } 6075 printf("%02x", (uint8_t) p[j]); 6076 } 6077 putchar(' '); 6078 for (j = i; j < end; j++) { 6079 if (isprint(p[j])) 6080 putchar(p[j]); 6081 else if (p[j] == 0) 6082 putchar('.'); 6083 else 6084 putchar(' '); 6085 } 6086 putchar('\n'); 6087 } 6088 } 6089 6090 struct loc_at { 6091 Dwarf_Attribute la_at; 6092 Dwarf_Unsigned la_off; 6093 Dwarf_Unsigned la_lowpc; 6094 Dwarf_Half la_cu_psize; 6095 Dwarf_Half la_cu_osize; 6096 Dwarf_Half la_cu_ver; 6097 TAILQ_ENTRY(loc_at) la_next; 6098 }; 6099 6100 static TAILQ_HEAD(, loc_at) lalist = TAILQ_HEAD_INITIALIZER(lalist); 6101 6102 static void 6103 search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc) 6104 { 6105 Dwarf_Attribute *attr_list; 6106 Dwarf_Die ret_die; 6107 Dwarf_Unsigned off; 6108 Dwarf_Off ref; 6109 Dwarf_Signed attr_count; 6110 Dwarf_Half attr, form; 6111 Dwarf_Bool is_info; 6112 Dwarf_Error de; 6113 struct loc_at *la, *nla; 6114 int i, ret; 6115 6116 is_info = dwarf_get_die_infotypes_flag(die); 6117 6118 if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != 6119 DW_DLV_OK) { 6120 if (ret == DW_DLV_ERROR) 6121 warnx("dwarf_attrlist failed: %s", dwarf_errmsg(de)); 6122 goto cont_search; 6123 } 6124 for (i = 0; i < attr_count; i++) { 6125 if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { 6126 warnx("dwarf_whatattr failed: %s", dwarf_errmsg(de)); 6127 continue; 6128 } 6129 if (attr != DW_AT_location && 6130 attr != DW_AT_string_length && 6131 attr != DW_AT_return_addr && 6132 attr != DW_AT_data_member_location && 6133 attr != DW_AT_frame_base && 6134 attr != DW_AT_segment && 6135 attr != DW_AT_static_link && 6136 attr != DW_AT_use_location && 6137 attr != DW_AT_vtable_elem_location) 6138 continue; 6139 if (dwarf_whatform(attr_list[i], &form, &de) != DW_DLV_OK) { 6140 warnx("dwarf_whatform failed: %s", dwarf_errmsg(de)); 6141 continue; 6142 } 6143 if (form == DW_FORM_data4 || form == DW_FORM_data8) { 6144 if (dwarf_formudata(attr_list[i], &off, &de) != 6145 DW_DLV_OK) { 6146 warnx("dwarf_formudata failed: %s", 6147 dwarf_errmsg(de)); 6148 continue; 6149 } 6150 } else if (form == DW_FORM_sec_offset) { 6151 if (dwarf_global_formref(attr_list[i], &ref, &de) != 6152 DW_DLV_OK) { 6153 warnx("dwarf_global_formref failed: %s", 6154 dwarf_errmsg(de)); 6155 continue; 6156 } 6157 off = ref; 6158 } else 6159 continue; 6160 6161 TAILQ_FOREACH(la, &lalist, la_next) { 6162 if (off == la->la_off) 6163 break; 6164 if (off < la->la_off) { 6165 if ((nla = malloc(sizeof(*nla))) == NULL) 6166 err(EXIT_FAILURE, "malloc failed"); 6167 nla->la_at = attr_list[i]; 6168 nla->la_off = off; 6169 nla->la_lowpc = lowpc; 6170 nla->la_cu_psize = re->cu_psize; 6171 nla->la_cu_osize = re->cu_osize; 6172 nla->la_cu_ver = re->cu_ver; 6173 TAILQ_INSERT_BEFORE(la, nla, la_next); 6174 break; 6175 } 6176 } 6177 if (la == NULL) { 6178 if ((nla = malloc(sizeof(*nla))) == NULL) 6179 err(EXIT_FAILURE, "malloc failed"); 6180 nla->la_at = attr_list[i]; 6181 nla->la_off = off; 6182 nla->la_lowpc = lowpc; 6183 nla->la_cu_psize = re->cu_psize; 6184 nla->la_cu_osize = re->cu_osize; 6185 nla->la_cu_ver = re->cu_ver; 6186 TAILQ_INSERT_TAIL(&lalist, nla, la_next); 6187 } 6188 } 6189 6190 cont_search: 6191 /* Search children. */ 6192 ret = dwarf_child(die, &ret_die, &de); 6193 if (ret == DW_DLV_ERROR) 6194 warnx("dwarf_child: %s", dwarf_errmsg(de)); 6195 else if (ret == DW_DLV_OK) 6196 search_loclist_at(re, ret_die, lowpc); 6197 6198 /* Search sibling. */ 6199 ret = dwarf_siblingof_b(re->dbg, die, &ret_die, is_info, &de); 6200 if (ret == DW_DLV_ERROR) 6201 warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); 6202 else if (ret == DW_DLV_OK) 6203 search_loclist_at(re, ret_die, lowpc); 6204 } 6205 6206 static void 6207 dump_dwarf_loc(struct readelf *re, Dwarf_Loc *lr) 6208 { 6209 const char *op_str; 6210 char unk_op[32]; 6211 uint8_t *b, n; 6212 int i; 6213 6214 if (dwarf_get_OP_name(lr->lr_atom, &op_str) != 6215 DW_DLV_OK) { 6216 snprintf(unk_op, sizeof(unk_op), 6217 "[Unknown OP: %#x]", lr->lr_atom); 6218 op_str = unk_op; 6219 } 6220 6221 printf("%s", op_str); 6222 6223 switch (lr->lr_atom) { 6224 case DW_OP_reg0: 6225 case DW_OP_reg1: 6226 case DW_OP_reg2: 6227 case DW_OP_reg3: 6228 case DW_OP_reg4: 6229 case DW_OP_reg5: 6230 case DW_OP_reg6: 6231 case DW_OP_reg7: 6232 case DW_OP_reg8: 6233 case DW_OP_reg9: 6234 case DW_OP_reg10: 6235 case DW_OP_reg11: 6236 case DW_OP_reg12: 6237 case DW_OP_reg13: 6238 case DW_OP_reg14: 6239 case DW_OP_reg15: 6240 case DW_OP_reg16: 6241 case DW_OP_reg17: 6242 case DW_OP_reg18: 6243 case DW_OP_reg19: 6244 case DW_OP_reg20: 6245 case DW_OP_reg21: 6246 case DW_OP_reg22: 6247 case DW_OP_reg23: 6248 case DW_OP_reg24: 6249 case DW_OP_reg25: 6250 case DW_OP_reg26: 6251 case DW_OP_reg27: 6252 case DW_OP_reg28: 6253 case DW_OP_reg29: 6254 case DW_OP_reg30: 6255 case DW_OP_reg31: 6256 printf(" (%s)", dwarf_regname(re, lr->lr_atom - DW_OP_reg0)); 6257 break; 6258 6259 case DW_OP_deref: 6260 case DW_OP_lit0: 6261 case DW_OP_lit1: 6262 case DW_OP_lit2: 6263 case DW_OP_lit3: 6264 case DW_OP_lit4: 6265 case DW_OP_lit5: 6266 case DW_OP_lit6: 6267 case DW_OP_lit7: 6268 case DW_OP_lit8: 6269 case DW_OP_lit9: 6270 case DW_OP_lit10: 6271 case DW_OP_lit11: 6272 case DW_OP_lit12: 6273 case DW_OP_lit13: 6274 case DW_OP_lit14: 6275 case DW_OP_lit15: 6276 case DW_OP_lit16: 6277 case DW_OP_lit17: 6278 case DW_OP_lit18: 6279 case DW_OP_lit19: 6280 case DW_OP_lit20: 6281 case DW_OP_lit21: 6282 case DW_OP_lit22: 6283 case DW_OP_lit23: 6284 case DW_OP_lit24: 6285 case DW_OP_lit25: 6286 case DW_OP_lit26: 6287 case DW_OP_lit27: 6288 case DW_OP_lit28: 6289 case DW_OP_lit29: 6290 case DW_OP_lit30: 6291 case DW_OP_lit31: 6292 case DW_OP_dup: 6293 case DW_OP_drop: 6294 case DW_OP_over: 6295 case DW_OP_swap: 6296 case DW_OP_rot: 6297 case DW_OP_xderef: 6298 case DW_OP_abs: 6299 case DW_OP_and: 6300 case DW_OP_div: 6301 case DW_OP_minus: 6302 case DW_OP_mod: 6303 case DW_OP_mul: 6304 case DW_OP_neg: 6305 case DW_OP_not: 6306 case DW_OP_or: 6307 case DW_OP_plus: 6308 case DW_OP_shl: 6309 case DW_OP_shr: 6310 case DW_OP_shra: 6311 case DW_OP_xor: 6312 case DW_OP_eq: 6313 case DW_OP_ge: 6314 case DW_OP_gt: 6315 case DW_OP_le: 6316 case DW_OP_lt: 6317 case DW_OP_ne: 6318 case DW_OP_nop: 6319 case DW_OP_push_object_address: 6320 case DW_OP_form_tls_address: 6321 case DW_OP_call_frame_cfa: 6322 case DW_OP_stack_value: 6323 case DW_OP_GNU_push_tls_address: 6324 case DW_OP_GNU_uninit: 6325 break; 6326 6327 case DW_OP_const1u: 6328 case DW_OP_pick: 6329 case DW_OP_deref_size: 6330 case DW_OP_xderef_size: 6331 case DW_OP_const2u: 6332 case DW_OP_bra: 6333 case DW_OP_skip: 6334 case DW_OP_const4u: 6335 case DW_OP_const8u: 6336 case DW_OP_constu: 6337 case DW_OP_plus_uconst: 6338 case DW_OP_regx: 6339 case DW_OP_piece: 6340 printf(": %ju", (uintmax_t) 6341 lr->lr_number); 6342 break; 6343 6344 case DW_OP_const1s: 6345 case DW_OP_const2s: 6346 case DW_OP_const4s: 6347 case DW_OP_const8s: 6348 case DW_OP_consts: 6349 printf(": %jd", (intmax_t) 6350 lr->lr_number); 6351 break; 6352 6353 case DW_OP_breg0: 6354 case DW_OP_breg1: 6355 case DW_OP_breg2: 6356 case DW_OP_breg3: 6357 case DW_OP_breg4: 6358 case DW_OP_breg5: 6359 case DW_OP_breg6: 6360 case DW_OP_breg7: 6361 case DW_OP_breg8: 6362 case DW_OP_breg9: 6363 case DW_OP_breg10: 6364 case DW_OP_breg11: 6365 case DW_OP_breg12: 6366 case DW_OP_breg13: 6367 case DW_OP_breg14: 6368 case DW_OP_breg15: 6369 case DW_OP_breg16: 6370 case DW_OP_breg17: 6371 case DW_OP_breg18: 6372 case DW_OP_breg19: 6373 case DW_OP_breg20: 6374 case DW_OP_breg21: 6375 case DW_OP_breg22: 6376 case DW_OP_breg23: 6377 case DW_OP_breg24: 6378 case DW_OP_breg25: 6379 case DW_OP_breg26: 6380 case DW_OP_breg27: 6381 case DW_OP_breg28: 6382 case DW_OP_breg29: 6383 case DW_OP_breg30: 6384 case DW_OP_breg31: 6385 printf(" (%s): %jd", 6386 dwarf_regname(re, lr->lr_atom - DW_OP_breg0), 6387 (intmax_t) lr->lr_number); 6388 break; 6389 6390 case DW_OP_fbreg: 6391 printf(": %jd", (intmax_t) 6392 lr->lr_number); 6393 break; 6394 6395 case DW_OP_bregx: 6396 printf(": %ju (%s) %jd", 6397 (uintmax_t) lr->lr_number, 6398 dwarf_regname(re, (unsigned int) lr->lr_number), 6399 (intmax_t) lr->lr_number2); 6400 break; 6401 6402 case DW_OP_addr: 6403 case DW_OP_GNU_encoded_addr: 6404 printf(": %#jx", (uintmax_t) 6405 lr->lr_number); 6406 break; 6407 6408 case DW_OP_GNU_implicit_pointer: 6409 printf(": <0x%jx> %jd", (uintmax_t) lr->lr_number, 6410 (intmax_t) lr->lr_number2); 6411 break; 6412 6413 case DW_OP_implicit_value: 6414 printf(": %ju byte block:", (uintmax_t) lr->lr_number); 6415 b = (uint8_t *)(uintptr_t) lr->lr_number2; 6416 for (i = 0; (Dwarf_Unsigned) i < lr->lr_number; i++) 6417 printf(" %x", b[i]); 6418 break; 6419 6420 case DW_OP_GNU_entry_value: 6421 printf(": ("); 6422 dump_dwarf_block(re, (uint8_t *)(uintptr_t) lr->lr_number2, 6423 lr->lr_number); 6424 putchar(')'); 6425 break; 6426 6427 case DW_OP_GNU_const_type: 6428 printf(": <0x%jx> ", (uintmax_t) lr->lr_number); 6429 b = (uint8_t *)(uintptr_t) lr->lr_number2; 6430 n = *b; 6431 for (i = 1; (uint8_t) i < n; i++) 6432 printf(" %x", b[i]); 6433 break; 6434 6435 case DW_OP_GNU_regval_type: 6436 printf(": %ju (%s) <0x%jx>", (uintmax_t) lr->lr_number, 6437 dwarf_regname(re, (unsigned int) lr->lr_number), 6438 (uintmax_t) lr->lr_number2); 6439 break; 6440 6441 case DW_OP_GNU_convert: 6442 case DW_OP_GNU_deref_type: 6443 case DW_OP_GNU_parameter_ref: 6444 case DW_OP_GNU_reinterpret: 6445 printf(": <0x%jx>", (uintmax_t) lr->lr_number); 6446 break; 6447 6448 default: 6449 break; 6450 } 6451 } 6452 6453 static void 6454 dump_dwarf_block(struct readelf *re, uint8_t *b, Dwarf_Unsigned len) 6455 { 6456 Dwarf_Locdesc *llbuf; 6457 Dwarf_Signed lcnt; 6458 Dwarf_Error de; 6459 int i; 6460 6461 if (dwarf_loclist_from_expr_b(re->dbg, b, len, re->cu_psize, 6462 re->cu_osize, re->cu_ver, &llbuf, &lcnt, &de) != DW_DLV_OK) { 6463 warnx("dwarf_loclist_form_expr_b: %s", dwarf_errmsg(de)); 6464 return; 6465 } 6466 6467 for (i = 0; (Dwarf_Half) i < llbuf->ld_cents; i++) { 6468 dump_dwarf_loc(re, &llbuf->ld_s[i]); 6469 if (i < llbuf->ld_cents - 1) 6470 printf("; "); 6471 } 6472 6473 dwarf_dealloc(re->dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); 6474 dwarf_dealloc(re->dbg, llbuf, DW_DLA_LOCDESC); 6475 } 6476 6477 static void 6478 dump_dwarf_loclist(struct readelf *re) 6479 { 6480 Dwarf_Die die; 6481 Dwarf_Locdesc **llbuf; 6482 Dwarf_Unsigned lowpc; 6483 Dwarf_Signed lcnt; 6484 Dwarf_Half tag, version, pointer_size, off_size; 6485 Dwarf_Error de; 6486 struct loc_at *la; 6487 int i, j, ret; 6488 6489 printf("\nContents of section .debug_loc:\n"); 6490 6491 /* Search .debug_info section. */ 6492 while ((ret = dwarf_next_cu_header_b(re->dbg, NULL, &version, NULL, 6493 &pointer_size, &off_size, NULL, NULL, &de)) == DW_DLV_OK) { 6494 set_cu_context(re, pointer_size, off_size, version); 6495 die = NULL; 6496 if (dwarf_siblingof(re->dbg, die, &die, &de) != DW_DLV_OK) 6497 continue; 6498 if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { 6499 warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); 6500 continue; 6501 } 6502 /* XXX: What about DW_TAG_partial_unit? */ 6503 lowpc = 0; 6504 if (tag == DW_TAG_compile_unit) { 6505 if (dwarf_attrval_unsigned(die, DW_AT_low_pc, 6506 &lowpc, &de) != DW_DLV_OK) 6507 lowpc = 0; 6508 } 6509 6510 /* Search attributes for reference to .debug_loc section. */ 6511 search_loclist_at(re, die, lowpc); 6512 } 6513 if (ret == DW_DLV_ERROR) 6514 warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); 6515 6516 /* Search .debug_types section. */ 6517 do { 6518 while ((ret = dwarf_next_cu_header_c(re->dbg, 0, NULL, 6519 &version, NULL, &pointer_size, &off_size, NULL, NULL, 6520 NULL, NULL, &de)) == DW_DLV_OK) { 6521 set_cu_context(re, pointer_size, off_size, version); 6522 die = NULL; 6523 if (dwarf_siblingof(re->dbg, die, &die, &de) != 6524 DW_DLV_OK) 6525 continue; 6526 if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { 6527 warnx("dwarf_tag failed: %s", 6528 dwarf_errmsg(de)); 6529 continue; 6530 } 6531 6532 lowpc = 0; 6533 if (tag == DW_TAG_type_unit) { 6534 if (dwarf_attrval_unsigned(die, DW_AT_low_pc, 6535 &lowpc, &de) != DW_DLV_OK) 6536 lowpc = 0; 6537 } 6538 6539 /* 6540 * Search attributes for reference to .debug_loc 6541 * section. 6542 */ 6543 search_loclist_at(re, die, lowpc); 6544 } 6545 if (ret == DW_DLV_ERROR) 6546 warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); 6547 } while (dwarf_next_types_section(re->dbg, &de) == DW_DLV_OK); 6548 6549 if (TAILQ_EMPTY(&lalist)) 6550 return; 6551 6552 printf(" Offset Begin End Expression\n"); 6553 6554 TAILQ_FOREACH(la, &lalist, la_next) { 6555 if (dwarf_loclist_n(la->la_at, &llbuf, &lcnt, &de) != 6556 DW_DLV_OK) { 6557 warnx("dwarf_loclist_n failed: %s", dwarf_errmsg(de)); 6558 continue; 6559 } 6560 set_cu_context(re, la->la_cu_psize, la->la_cu_osize, 6561 la->la_cu_ver); 6562 for (i = 0; i < lcnt; i++) { 6563 printf(" %8.8jx ", la->la_off); 6564 if (llbuf[i]->ld_lopc == 0 && llbuf[i]->ld_hipc == 0) { 6565 printf("<End of list>\n"); 6566 continue; 6567 } 6568 6569 /* TODO: handle base selection entry. */ 6570 6571 printf("%8.8jx %8.8jx ", 6572 (uintmax_t) (la->la_lowpc + llbuf[i]->ld_lopc), 6573 (uintmax_t) (la->la_lowpc + llbuf[i]->ld_hipc)); 6574 6575 putchar('('); 6576 for (j = 0; (Dwarf_Half) j < llbuf[i]->ld_cents; j++) { 6577 dump_dwarf_loc(re, &llbuf[i]->ld_s[j]); 6578 if (j < llbuf[i]->ld_cents - 1) 6579 printf("; "); 6580 } 6581 putchar(')'); 6582 6583 if (llbuf[i]->ld_lopc == llbuf[i]->ld_hipc) 6584 printf(" (start == end)"); 6585 putchar('\n'); 6586 } 6587 for (i = 0; i < lcnt; i++) { 6588 dwarf_dealloc(re->dbg, llbuf[i]->ld_s, 6589 DW_DLA_LOC_BLOCK); 6590 dwarf_dealloc(re->dbg, llbuf[i], DW_DLA_LOCDESC); 6591 } 6592 dwarf_dealloc(re->dbg, llbuf, DW_DLA_LIST); 6593 } 6594 } 6595 6596 /* 6597 * Retrieve a string using string table section index and the string offset. 6598 */ 6599 static const char* 6600 get_string(struct readelf *re, int strtab, size_t off) 6601 { 6602 const char *name; 6603 6604 if ((name = elf_strptr(re->elf, strtab, off)) == NULL) 6605 return (""); 6606 6607 return (name); 6608 } 6609 6610 /* 6611 * Retrieve the name of a symbol using the section index of the symbol 6612 * table and the index of the symbol within that table. 6613 */ 6614 static const char * 6615 get_symbol_name(struct readelf *re, int symtab, int i) 6616 { 6617 struct section *s; 6618 const char *name; 6619 GElf_Sym sym; 6620 Elf_Data *data; 6621 int elferr; 6622 6623 s = &re->sl[symtab]; 6624 if (s->type != SHT_SYMTAB && s->type != SHT_DYNSYM) 6625 return (""); 6626 (void) elf_errno(); 6627 if ((data = elf_getdata(s->scn, NULL)) == NULL) { 6628 elferr = elf_errno(); 6629 if (elferr != 0) 6630 warnx("elf_getdata failed: %s", elf_errmsg(elferr)); 6631 return (""); 6632 } 6633 if (gelf_getsym(data, i, &sym) != &sym) 6634 return (""); 6635 /* Return section name for STT_SECTION symbol. */ 6636 if (GELF_ST_TYPE(sym.st_info) == STT_SECTION && 6637 re->sl[sym.st_shndx].name != NULL) 6638 return (re->sl[sym.st_shndx].name); 6639 if ((name = elf_strptr(re->elf, s->link, sym.st_name)) == NULL) 6640 return (""); 6641 6642 return (name); 6643 } 6644 6645 static uint64_t 6646 get_symbol_value(struct readelf *re, int symtab, int i) 6647 { 6648 struct section *s; 6649 GElf_Sym sym; 6650 Elf_Data *data; 6651 int elferr; 6652 6653 s = &re->sl[symtab]; 6654 if (s->type != SHT_SYMTAB && s->type != SHT_DYNSYM) 6655 return (0); 6656 (void) elf_errno(); 6657 if ((data = elf_getdata(s->scn, NULL)) == NULL) { 6658 elferr = elf_errno(); 6659 if (elferr != 0) 6660 warnx("elf_getdata failed: %s", elf_errmsg(elferr)); 6661 return (0); 6662 } 6663 if (gelf_getsym(data, i, &sym) != &sym) 6664 return (0); 6665 6666 return (sym.st_value); 6667 } 6668 6669 static void 6670 hex_dump(struct readelf *re) 6671 { 6672 struct section *s; 6673 Elf_Data *d; 6674 uint8_t *buf; 6675 size_t sz, nbytes; 6676 uint64_t addr; 6677 int elferr, i, j; 6678 6679 for (i = 1; (size_t) i < re->shnum; i++) { 6680 s = &re->sl[i]; 6681 if (find_dumpop(re, (size_t) i, s->name, HEX_DUMP, -1) == NULL) 6682 continue; 6683 (void) elf_errno(); 6684 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 6685 elferr = elf_errno(); 6686 if (elferr != 0) 6687 warnx("elf_getdata failed: %s", 6688 elf_errmsg(elferr)); 6689 continue; 6690 } 6691 if (d->d_size <= 0 || d->d_buf == NULL) { 6692 printf("\nSection '%s' has no data to dump.\n", 6693 s->name); 6694 continue; 6695 } 6696 buf = d->d_buf; 6697 sz = d->d_size; 6698 addr = s->addr; 6699 printf("\nHex dump of section '%s':\n", s->name); 6700 while (sz > 0) { 6701 printf(" 0x%8.8jx ", (uintmax_t)addr); 6702 nbytes = sz > 16? 16 : sz; 6703 for (j = 0; j < 16; j++) { 6704 if ((size_t)j < nbytes) 6705 printf("%2.2x", buf[j]); 6706 else 6707 printf(" "); 6708 if ((j & 3) == 3) 6709 printf(" "); 6710 } 6711 for (j = 0; (size_t)j < nbytes; j++) { 6712 if (isprint(buf[j])) 6713 printf("%c", buf[j]); 6714 else 6715 printf("."); 6716 } 6717 printf("\n"); 6718 buf += nbytes; 6719 addr += nbytes; 6720 sz -= nbytes; 6721 } 6722 } 6723 } 6724 6725 static void 6726 str_dump(struct readelf *re) 6727 { 6728 struct section *s; 6729 Elf_Data *d; 6730 unsigned char *start, *end, *buf_end; 6731 unsigned int len; 6732 int i, j, elferr, found; 6733 6734 for (i = 1; (size_t) i < re->shnum; i++) { 6735 s = &re->sl[i]; 6736 if (find_dumpop(re, (size_t) i, s->name, STR_DUMP, -1) == NULL) 6737 continue; 6738 (void) elf_errno(); 6739 if ((d = elf_getdata(s->scn, NULL)) == NULL) { 6740 elferr = elf_errno(); 6741 if (elferr != 0) 6742 warnx("elf_getdata failed: %s", 6743 elf_errmsg(elferr)); 6744 continue; 6745 } 6746 if (d->d_size <= 0 || d->d_buf == NULL) { 6747 printf("\nSection '%s' has no data to dump.\n", 6748 s->name); 6749 continue; 6750 } 6751 buf_end = (unsigned char *) d->d_buf + d->d_size; 6752 start = (unsigned char *) d->d_buf; 6753 found = 0; 6754 printf("\nString dump of section '%s':\n", s->name); 6755 for (;;) { 6756 while (start < buf_end && !isprint(*start)) 6757 start++; 6758 if (start >= buf_end) 6759 break; 6760 end = start + 1; 6761 while (end < buf_end && isprint(*end)) 6762 end++; 6763 printf(" [%6lx] ", 6764 (long) (start - (unsigned char *) d->d_buf)); 6765 len = end - start; 6766 for (j = 0; (unsigned int) j < len; j++) 6767 putchar(start[j]); 6768 putchar('\n'); 6769 found = 1; 6770 if (end >= buf_end) 6771 break; 6772 start = end + 1; 6773 } 6774 if (!found) 6775 printf(" No strings found in this section."); 6776 putchar('\n'); 6777 } 6778 } 6779 6780 static void 6781 load_sections(struct readelf *re) 6782 { 6783 struct section *s; 6784 const char *name; 6785 Elf_Scn *scn; 6786 GElf_Shdr sh; 6787 size_t shstrndx, ndx; 6788 int elferr; 6789 6790 /* Allocate storage for internal section list. */ 6791 if (!elf_getshnum(re->elf, &re->shnum)) { 6792 warnx("elf_getshnum failed: %s", elf_errmsg(-1)); 6793 return; 6794 } 6795 if (re->sl != NULL) 6796 free(re->sl); 6797 if ((re->sl = calloc(re->shnum, sizeof(*re->sl))) == NULL) 6798 err(EXIT_FAILURE, "calloc failed"); 6799 6800 /* Get the index of .shstrtab section. */ 6801 if (!elf_getshstrndx(re->elf, &shstrndx)) { 6802 warnx("elf_getshstrndx failed: %s", elf_errmsg(-1)); 6803 return; 6804 } 6805 6806 if ((scn = elf_getscn(re->elf, 0)) == NULL) 6807 return; 6808 6809 (void) elf_errno(); 6810 do { 6811 if (gelf_getshdr(scn, &sh) == NULL) { 6812 warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); 6813 (void) elf_errno(); 6814 continue; 6815 } 6816 if ((name = elf_strptr(re->elf, shstrndx, sh.sh_name)) == NULL) { 6817 (void) elf_errno(); 6818 name = "ERROR"; 6819 } 6820 if ((ndx = elf_ndxscn(scn)) == SHN_UNDEF) { 6821 if ((elferr = elf_errno()) != 0) 6822 warnx("elf_ndxscn failed: %s", 6823 elf_errmsg(elferr)); 6824 continue; 6825 } 6826 if (ndx >= re->shnum) { 6827 warnx("section index of '%s' out of range", name); 6828 continue; 6829 } 6830 s = &re->sl[ndx]; 6831 s->name = name; 6832 s->scn = scn; 6833 s->off = sh.sh_offset; 6834 s->sz = sh.sh_size; 6835 s->entsize = sh.sh_entsize; 6836 s->align = sh.sh_addralign; 6837 s->type = sh.sh_type; 6838 s->flags = sh.sh_flags; 6839 s->addr = sh.sh_addr; 6840 s->link = sh.sh_link; 6841 s->info = sh.sh_info; 6842 } while ((scn = elf_nextscn(re->elf, scn)) != NULL); 6843 elferr = elf_errno(); 6844 if (elferr != 0) 6845 warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); 6846 } 6847 6848 static void 6849 unload_sections(struct readelf *re) 6850 { 6851 6852 if (re->sl != NULL) { 6853 free(re->sl); 6854 re->sl = NULL; 6855 } 6856 re->shnum = 0; 6857 re->vd_s = NULL; 6858 re->vn_s = NULL; 6859 re->vs_s = NULL; 6860 re->vs = NULL; 6861 re->vs_sz = 0; 6862 if (re->ver != NULL) { 6863 free(re->ver); 6864 re->ver = NULL; 6865 re->ver_sz = 0; 6866 } 6867 } 6868 6869 static void 6870 dump_elf(struct readelf *re) 6871 { 6872 6873 /* Fetch ELF header. No need to continue if it fails. */ 6874 if (gelf_getehdr(re->elf, &re->ehdr) == NULL) { 6875 warnx("gelf_getehdr failed: %s", elf_errmsg(-1)); 6876 return; 6877 } 6878 if ((re->ec = gelf_getclass(re->elf)) == ELFCLASSNONE) { 6879 warnx("gelf_getclass failed: %s", elf_errmsg(-1)); 6880 return; 6881 } 6882 if (re->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) { 6883 re->dw_read = _read_msb; 6884 re->dw_decode = _decode_msb; 6885 } else { 6886 re->dw_read = _read_lsb; 6887 re->dw_decode = _decode_lsb; 6888 } 6889 6890 if (re->options & ~RE_H) 6891 load_sections(re); 6892 if ((re->options & RE_VV) || (re->options & RE_S)) 6893 search_ver(re); 6894 if (re->options & RE_H) 6895 dump_ehdr(re); 6896 if (re->options & RE_L) 6897 dump_phdr(re); 6898 if (re->options & RE_SS) 6899 dump_shdr(re); 6900 if (re->options & RE_G) 6901 dump_section_groups(re); 6902 if (re->options & RE_D) 6903 dump_dynamic(re); 6904 if (re->options & RE_R) 6905 dump_reloc(re); 6906 if (re->options & RE_S) 6907 dump_symtabs(re); 6908 if (re->options & RE_N) 6909 dump_notes(re); 6910 if (re->options & RE_II) 6911 dump_hash(re); 6912 if (re->options & RE_X) 6913 hex_dump(re); 6914 if (re->options & RE_P) 6915 str_dump(re); 6916 if (re->options & RE_VV) 6917 dump_ver(re); 6918 if (re->options & RE_AA) 6919 dump_arch_specific_info(re); 6920 if (re->options & RE_W) 6921 dump_dwarf(re); 6922 if (re->options & ~RE_H) 6923 unload_sections(re); 6924 } 6925 6926 static void 6927 dump_dwarf(struct readelf *re) 6928 { 6929 int error; 6930 Dwarf_Error de; 6931 6932 if (dwarf_elf_init(re->elf, DW_DLC_READ, NULL, NULL, &re->dbg, &de)) { 6933 if ((error = dwarf_errno(de)) != DW_DLE_DEBUG_INFO_NULL) 6934 errx(EXIT_FAILURE, "dwarf_elf_init failed: %s", 6935 dwarf_errmsg(de)); 6936 return; 6937 } 6938 6939 if (re->dop & DW_A) 6940 dump_dwarf_abbrev(re); 6941 if (re->dop & DW_L) 6942 dump_dwarf_line(re); 6943 if (re->dop & DW_LL) 6944 dump_dwarf_line_decoded(re); 6945 if (re->dop & DW_I) { 6946 dump_dwarf_info(re, 0); 6947 dump_dwarf_info(re, 1); 6948 } 6949 if (re->dop & DW_P) 6950 dump_dwarf_pubnames(re); 6951 if (re->dop & DW_R) 6952 dump_dwarf_aranges(re); 6953 if (re->dop & DW_RR) 6954 dump_dwarf_ranges(re); 6955 if (re->dop & DW_M) 6956 dump_dwarf_macinfo(re); 6957 if (re->dop & DW_F) 6958 dump_dwarf_frame(re, 0); 6959 else if (re->dop & DW_FF) 6960 dump_dwarf_frame(re, 1); 6961 if (re->dop & DW_S) 6962 dump_dwarf_str(re); 6963 if (re->dop & DW_O) 6964 dump_dwarf_loclist(re); 6965 6966 dwarf_finish(re->dbg, &de); 6967 } 6968 6969 static void 6970 dump_ar(struct readelf *re, int fd) 6971 { 6972 Elf_Arsym *arsym; 6973 Elf_Arhdr *arhdr; 6974 Elf_Cmd cmd; 6975 Elf *e; 6976 size_t sz; 6977 off_t off; 6978 int i; 6979 6980 re->ar = re->elf; 6981 6982 if (re->options & RE_C) { 6983 if ((arsym = elf_getarsym(re->ar, &sz)) == NULL) { 6984 warnx("elf_getarsym() failed: %s", elf_errmsg(-1)); 6985 goto process_members; 6986 } 6987 printf("Index of archive %s: (%ju entries)\n", re->filename, 6988 (uintmax_t) sz - 1); 6989 off = 0; 6990 for (i = 0; (size_t) i < sz; i++) { 6991 if (arsym[i].as_name == NULL) 6992 break; 6993 if (arsym[i].as_off != off) { 6994 off = arsym[i].as_off; 6995 if (elf_rand(re->ar, off) != off) { 6996 warnx("elf_rand() failed: %s", 6997 elf_errmsg(-1)); 6998 continue; 6999 } 7000 if ((e = elf_begin(fd, ELF_C_READ, re->ar)) == 7001 NULL) { 7002 warnx("elf_begin() failed: %s", 7003 elf_errmsg(-1)); 7004 continue; 7005 } 7006 if ((arhdr = elf_getarhdr(e)) == NULL) { 7007 warnx("elf_getarhdr() failed: %s", 7008 elf_errmsg(-1)); 7009 elf_end(e); 7010 continue; 7011 } 7012 printf("Binary %s(%s) contains:\n", 7013 re->filename, arhdr->ar_name); 7014 } 7015 printf("\t%s\n", arsym[i].as_name); 7016 } 7017 if (elf_rand(re->ar, SARMAG) != SARMAG) { 7018 warnx("elf_rand() failed: %s", elf_errmsg(-1)); 7019 return; 7020 } 7021 } 7022 7023 process_members: 7024 7025 if ((re->options & ~RE_C) == 0) 7026 return; 7027 7028 cmd = ELF_C_READ; 7029 while ((re->elf = elf_begin(fd, cmd, re->ar)) != NULL) { 7030 if ((arhdr = elf_getarhdr(re->elf)) == NULL) { 7031 warnx("elf_getarhdr() failed: %s", elf_errmsg(-1)); 7032 goto next_member; 7033 } 7034 if (strcmp(arhdr->ar_name, "/") == 0 || 7035 strcmp(arhdr->ar_name, "//") == 0 || 7036 strcmp(arhdr->ar_name, "__.SYMDEF") == 0) 7037 goto next_member; 7038 printf("\nFile: %s(%s)\n", re->filename, arhdr->ar_name); 7039 dump_elf(re); 7040 7041 next_member: 7042 cmd = elf_next(re->elf); 7043 elf_end(re->elf); 7044 } 7045 re->elf = re->ar; 7046 } 7047 7048 static void 7049 dump_object(struct readelf *re) 7050 { 7051 int fd; 7052 7053 if ((fd = open(re->filename, O_RDONLY)) == -1) { 7054 warn("open %s failed", re->filename); 7055 return; 7056 } 7057 7058 if ((re->flags & DISPLAY_FILENAME) != 0) 7059 printf("\nFile: %s\n", re->filename); 7060 7061 if ((re->elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { 7062 warnx("elf_begin() failed: %s", elf_errmsg(-1)); 7063 return; 7064 } 7065 7066 switch (elf_kind(re->elf)) { 7067 case ELF_K_NONE: 7068 warnx("Not an ELF file."); 7069 return; 7070 case ELF_K_ELF: 7071 dump_elf(re); 7072 break; 7073 case ELF_K_AR: 7074 dump_ar(re, fd); 7075 break; 7076 default: 7077 warnx("Internal: libelf returned unknown elf kind."); 7078 return; 7079 } 7080 7081 elf_end(re->elf); 7082 } 7083 7084 static void 7085 add_dumpop(struct readelf *re, size_t si, const char *sn, int op, int t) 7086 { 7087 struct dumpop *d; 7088 7089 if ((d = find_dumpop(re, si, sn, -1, t)) == NULL) { 7090 if ((d = calloc(1, sizeof(*d))) == NULL) 7091 err(EXIT_FAILURE, "calloc failed"); 7092 if (t == DUMP_BY_INDEX) 7093 d->u.si = si; 7094 else 7095 d->u.sn = sn; 7096 d->type = t; 7097 d->op = op; 7098 STAILQ_INSERT_TAIL(&re->v_dumpop, d, dumpop_list); 7099 } else 7100 d->op |= op; 7101 } 7102 7103 static struct dumpop * 7104 find_dumpop(struct readelf *re, size_t si, const char *sn, int op, int t) 7105 { 7106 struct dumpop *d; 7107 7108 STAILQ_FOREACH(d, &re->v_dumpop, dumpop_list) { 7109 if ((op == -1 || op & d->op) && 7110 (t == -1 || (unsigned) t == d->type)) { 7111 if ((d->type == DUMP_BY_INDEX && d->u.si == si) || 7112 (d->type == DUMP_BY_NAME && !strcmp(d->u.sn, sn))) 7113 return (d); 7114 } 7115 } 7116 7117 return (NULL); 7118 } 7119 7120 static struct { 7121 const char *ln; 7122 char sn; 7123 int value; 7124 } dwarf_op[] = { 7125 {"rawline", 'l', DW_L}, 7126 {"decodedline", 'L', DW_LL}, 7127 {"info", 'i', DW_I}, 7128 {"abbrev", 'a', DW_A}, 7129 {"pubnames", 'p', DW_P}, 7130 {"aranges", 'r', DW_R}, 7131 {"ranges", 'r', DW_R}, 7132 {"Ranges", 'R', DW_RR}, 7133 {"macro", 'm', DW_M}, 7134 {"frames", 'f', DW_F}, 7135 {"frames-interp", 'F', DW_FF}, 7136 {"str", 's', DW_S}, 7137 {"loc", 'o', DW_O}, 7138 {NULL, 0, 0} 7139 }; 7140 7141 static void 7142 parse_dwarf_op_short(struct readelf *re, const char *op) 7143 { 7144 int i; 7145 7146 if (op == NULL) { 7147 re->dop |= DW_DEFAULT_OPTIONS; 7148 return; 7149 } 7150 7151 for (; *op != '\0'; op++) { 7152 for (i = 0; dwarf_op[i].ln != NULL; i++) { 7153 if (dwarf_op[i].sn == *op) { 7154 re->dop |= dwarf_op[i].value; 7155 break; 7156 } 7157 } 7158 } 7159 } 7160 7161 static void 7162 parse_dwarf_op_long(struct readelf *re, const char *op) 7163 { 7164 char *p, *token, *bp; 7165 int i; 7166 7167 if (op == NULL) { 7168 re->dop |= DW_DEFAULT_OPTIONS; 7169 return; 7170 } 7171 7172 if ((p = strdup(op)) == NULL) 7173 err(EXIT_FAILURE, "strdup failed"); 7174 bp = p; 7175 7176 while ((token = strsep(&p, ",")) != NULL) { 7177 for (i = 0; dwarf_op[i].ln != NULL; i++) { 7178 if (!strcmp(token, dwarf_op[i].ln)) { 7179 re->dop |= dwarf_op[i].value; 7180 break; 7181 } 7182 } 7183 } 7184 7185 free(bp); 7186 } 7187 7188 static uint64_t 7189 _read_lsb(Elf_Data *d, uint64_t *offsetp, int bytes_to_read) 7190 { 7191 uint64_t ret; 7192 uint8_t *src; 7193 7194 src = (uint8_t *) d->d_buf + *offsetp; 7195 7196 ret = 0; 7197 switch (bytes_to_read) { 7198 case 8: 7199 ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; 7200 ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; 7201 case 4: 7202 ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; 7203 case 2: 7204 ret |= ((uint64_t) src[1]) << 8; 7205 case 1: 7206 ret |= src[0]; 7207 break; 7208 default: 7209 return (0); 7210 } 7211 7212 *offsetp += bytes_to_read; 7213 7214 return (ret); 7215 } 7216 7217 static uint64_t 7218 _read_msb(Elf_Data *d, uint64_t *offsetp, int bytes_to_read) 7219 { 7220 uint64_t ret; 7221 uint8_t *src; 7222 7223 src = (uint8_t *) d->d_buf + *offsetp; 7224 7225 switch (bytes_to_read) { 7226 case 1: 7227 ret = src[0]; 7228 break; 7229 case 2: 7230 ret = src[1] | ((uint64_t) src[0]) << 8; 7231 break; 7232 case 4: 7233 ret = src[3] | ((uint64_t) src[2]) << 8; 7234 ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; 7235 break; 7236 case 8: 7237 ret = src[7] | ((uint64_t) src[6]) << 8; 7238 ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; 7239 ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; 7240 ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; 7241 break; 7242 default: 7243 return (0); 7244 } 7245 7246 *offsetp += bytes_to_read; 7247 7248 return (ret); 7249 } 7250 7251 static uint64_t 7252 _decode_lsb(uint8_t **data, int bytes_to_read) 7253 { 7254 uint64_t ret; 7255 uint8_t *src; 7256 7257 src = *data; 7258 7259 ret = 0; 7260 switch (bytes_to_read) { 7261 case 8: 7262 ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; 7263 ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; 7264 case 4: 7265 ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; 7266 case 2: 7267 ret |= ((uint64_t) src[1]) << 8; 7268 case 1: 7269 ret |= src[0]; 7270 break; 7271 default: 7272 return (0); 7273 } 7274 7275 *data += bytes_to_read; 7276 7277 return (ret); 7278 } 7279 7280 static uint64_t 7281 _decode_msb(uint8_t **data, int bytes_to_read) 7282 { 7283 uint64_t ret; 7284 uint8_t *src; 7285 7286 src = *data; 7287 7288 ret = 0; 7289 switch (bytes_to_read) { 7290 case 1: 7291 ret = src[0]; 7292 break; 7293 case 2: 7294 ret = src[1] | ((uint64_t) src[0]) << 8; 7295 break; 7296 case 4: 7297 ret = src[3] | ((uint64_t) src[2]) << 8; 7298 ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; 7299 break; 7300 case 8: 7301 ret = src[7] | ((uint64_t) src[6]) << 8; 7302 ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; 7303 ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; 7304 ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; 7305 break; 7306 default: 7307 return (0); 7308 break; 7309 } 7310 7311 *data += bytes_to_read; 7312 7313 return (ret); 7314 } 7315 7316 static int64_t 7317 _decode_sleb128(uint8_t **dp) 7318 { 7319 int64_t ret = 0; 7320 uint8_t b; 7321 int shift = 0; 7322 7323 uint8_t *src = *dp; 7324 7325 do { 7326 b = *src++; 7327 ret |= ((b & 0x7f) << shift); 7328 shift += 7; 7329 } while ((b & 0x80) != 0); 7330 7331 if (shift < 32 && (b & 0x40) != 0) 7332 ret |= (-1 << shift); 7333 7334 *dp = src; 7335 7336 return (ret); 7337 } 7338 7339 static uint64_t 7340 _decode_uleb128(uint8_t **dp) 7341 { 7342 uint64_t ret = 0; 7343 uint8_t b; 7344 int shift = 0; 7345 7346 uint8_t *src = *dp; 7347 7348 do { 7349 b = *src++; 7350 ret |= ((b & 0x7f) << shift); 7351 shift += 7; 7352 } while ((b & 0x80) != 0); 7353 7354 *dp = src; 7355 7356 return (ret); 7357 } 7358 7359 static void 7360 readelf_version(void) 7361 { 7362 (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), 7363 elftc_version()); 7364 exit(EXIT_SUCCESS); 7365 } 7366 7367 #define USAGE_MESSAGE "\ 7368 Usage: %s [options] file...\n\ 7369 Display information about ELF objects and ar(1) archives.\n\n\ 7370 Options:\n\ 7371 -a | --all Equivalent to specifying options '-dhIlrsASV'.\n\ 7372 -c | --archive-index Print the archive symbol table for archives.\n\ 7373 -d | --dynamic Print the contents of SHT_DYNAMIC sections.\n\ 7374 -e | --headers Print all headers in the object.\n\ 7375 -g | --section-groups Print the contents of the section groups.\n\ 7376 -h | --file-header Print the file header for the object.\n\ 7377 -l | --program-headers Print the PHDR table for the object.\n\ 7378 -n | --notes Print the contents of SHT_NOTE sections.\n\ 7379 -p INDEX | --string-dump=INDEX\n\ 7380 Print the contents of section at index INDEX.\n\ 7381 -r | --relocs Print relocation information.\n\ 7382 -s | --syms | --symbols Print symbol tables.\n\ 7383 -t | --section-details Print additional information about sections.\n\ 7384 -v | --version Print a version identifier and exit.\n\ 7385 -x INDEX | --hex-dump=INDEX\n\ 7386 Display contents of a section as hexadecimal.\n\ 7387 -A | --arch-specific (accepted, but ignored)\n\ 7388 -D | --use-dynamic Print the symbol table specified by the DT_SYMTAB\n\ 7389 entry in the \".dynamic\" section.\n\ 7390 -H | --help Print a help message.\n\ 7391 -I | --histogram Print information on bucket list lengths for \n\ 7392 hash sections.\n\ 7393 -N | --full-section-name (accepted, but ignored)\n\ 7394 -S | --sections | --section-headers\n\ 7395 Print information about section headers.\n\ 7396 -V | --version-info Print symbol versoning information.\n\ 7397 -W | --wide Print information without wrapping long lines.\n" 7398 7399 7400 static void 7401 readelf_usage(void) 7402 { 7403 fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); 7404 exit(EXIT_FAILURE); 7405 } 7406 7407 int 7408 main(int argc, char **argv) 7409 { 7410 struct readelf *re, re_storage; 7411 unsigned long si; 7412 int opt, i; 7413 char *ep; 7414 7415 re = &re_storage; 7416 memset(re, 0, sizeof(*re)); 7417 STAILQ_INIT(&re->v_dumpop); 7418 7419 while ((opt = getopt_long(argc, argv, "AacDdegHhIi:lNnp:rSstuVvWw::x:", 7420 longopts, NULL)) != -1) { 7421 switch(opt) { 7422 case '?': 7423 readelf_usage(); 7424 break; 7425 case 'A': 7426 re->options |= RE_AA; 7427 break; 7428 case 'a': 7429 re->options |= RE_AA | RE_D | RE_G | RE_H | RE_II | 7430 RE_L | RE_R | RE_SS | RE_S | RE_VV; 7431 break; 7432 case 'c': 7433 re->options |= RE_C; 7434 break; 7435 case 'D': 7436 re->options |= RE_DD; 7437 break; 7438 case 'd': 7439 re->options |= RE_D; 7440 break; 7441 case 'e': 7442 re->options |= RE_H | RE_L | RE_SS; 7443 break; 7444 case 'g': 7445 re->options |= RE_G; 7446 break; 7447 case 'H': 7448 readelf_usage(); 7449 break; 7450 case 'h': 7451 re->options |= RE_H; 7452 break; 7453 case 'I': 7454 re->options |= RE_II; 7455 break; 7456 case 'i': 7457 /* Not implemented yet. */ 7458 break; 7459 case 'l': 7460 re->options |= RE_L; 7461 break; 7462 case 'N': 7463 re->options |= RE_NN; 7464 break; 7465 case 'n': 7466 re->options |= RE_N; 7467 break; 7468 case 'p': 7469 re->options |= RE_P; 7470 si = strtoul(optarg, &ep, 10); 7471 if (*ep == '\0') 7472 add_dumpop(re, (size_t) si, NULL, STR_DUMP, 7473 DUMP_BY_INDEX); 7474 else 7475 add_dumpop(re, 0, optarg, STR_DUMP, 7476 DUMP_BY_NAME); 7477 break; 7478 case 'r': 7479 re->options |= RE_R; 7480 break; 7481 case 'S': 7482 re->options |= RE_SS; 7483 break; 7484 case 's': 7485 re->options |= RE_S; 7486 break; 7487 case 't': 7488 re->options |= RE_T; 7489 break; 7490 case 'u': 7491 re->options |= RE_U; 7492 break; 7493 case 'V': 7494 re->options |= RE_VV; 7495 break; 7496 case 'v': 7497 readelf_version(); 7498 break; 7499 case 'W': 7500 re->options |= RE_WW; 7501 break; 7502 case 'w': 7503 re->options |= RE_W; 7504 parse_dwarf_op_short(re, optarg); 7505 break; 7506 case 'x': 7507 re->options |= RE_X; 7508 si = strtoul(optarg, &ep, 10); 7509 if (*ep == '\0') 7510 add_dumpop(re, (size_t) si, NULL, HEX_DUMP, 7511 DUMP_BY_INDEX); 7512 else 7513 add_dumpop(re, 0, optarg, HEX_DUMP, 7514 DUMP_BY_NAME); 7515 break; 7516 case OPTION_DEBUG_DUMP: 7517 re->options |= RE_W; 7518 parse_dwarf_op_long(re, optarg); 7519 } 7520 } 7521 7522 argv += optind; 7523 argc -= optind; 7524 7525 if (argc == 0 || re->options == 0) 7526 readelf_usage(); 7527 7528 if (argc > 1) 7529 re->flags |= DISPLAY_FILENAME; 7530 7531 if (elf_version(EV_CURRENT) == EV_NONE) 7532 errx(EXIT_FAILURE, "ELF library initialization failed: %s", 7533 elf_errmsg(-1)); 7534 7535 for (i = 0; i < argc; i++) { 7536 re->filename = argv[i]; 7537 dump_object(re); 7538 } 7539 7540 exit(EXIT_SUCCESS); 7541 } 7542