objdump.c revision 68765
1139965Simp/* objdump.c -- dump information about an object file. 21556Srgrimes Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 31556Srgrimes Free Software Foundation, Inc. 496196Sdes 596196SdesThis file is part of GNU Binutils. 61556Srgrimes 796196SdesThis program is free software; you can redistribute it and/or modify 896196Sdesit under the terms of the GNU General Public License as published by 996196Sdesthe Free Software Foundation; either version 2, or (at your option) 1096196Sdesany later version. 1196196Sdes 121556SrgrimesThis program is distributed in the hope that it will be useful, 131556Srgrimesbut WITHOUT ANY WARRANTY; without even the implied warranty of 141556SrgrimesMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 151556SrgrimesGNU General Public License for more details. 161556Srgrimes 171556SrgrimesYou should have received a copy of the GNU General Public License 181556Srgrimesalong with this program; if not, write to the Free Software 191556SrgrimesFoundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 201556Srgrimes 211556Srgrimes#include "bfd.h" 221556Srgrimes#include "getopt.h" 231556Srgrimes#include "progress.h" 241556Srgrimes#include "bucomm.h" 251556Srgrimes#include <ctype.h> 261556Srgrimes#include "dis-asm.h" 271556Srgrimes#include "libiberty.h" 281556Srgrimes#include "demangle.h" 291556Srgrimes#include "debug.h" 301556Srgrimes#include "budbg.h" 311556Srgrimes 321556Srgrimes/* Internal headers for the ELF .stab-dump code - sorry. */ 331556Srgrimes#define BYTES_IN_WORD 32 341556Srgrimes#include "aout/aout64.h" 351556Srgrimes 361556Srgrimes#ifdef NEED_DECLARATION_FPRINTF 37114433Sobrien/* This is needed by INIT_DISASSEMBLE_INFO. */ 381556Srgrimesextern int fprintf PARAMS ((FILE *, const char *, ...)); 3920420Ssteve#endif 401556Srgrimes 411556Srgrimes/* Exit status. */ 421556Srgrimesstatic int exit_status = 0; 431556Srgrimes 441556Srgrimesstatic char *default_target = NULL; /* default at runtime */ 4536149Scharnier 46104559Scharnierstatic int show_version = 0; /* show the version number */ 4736149Scharnierstatic int dump_section_contents; /* -s */ 4899110Sobrienstatic int dump_section_headers; /* -h */ 4999110Sobrienstatic boolean dump_file_header; /* -f */ 501556Srgrimesstatic int dump_symtab; /* -t */ 511556Srgrimesstatic int dump_dynamic_symtab; /* -T */ 521556Srgrimesstatic int dump_reloc_info; /* -r */ 531556Srgrimesstatic int dump_dynamic_reloc_info; /* -R */ 541556Srgrimesstatic int dump_ar_hdrs; /* -a */ 551556Srgrimesstatic int dump_private_headers; /* -p */ 561556Srgrimesstatic int prefix_addresses; /* --prefix-addresses */ 571556Srgrimesstatic int with_line_numbers; /* -l */ 581556Srgrimesstatic boolean with_source_code; /* -S */ 591556Srgrimesstatic int show_raw_insn; /* --show-raw-insn */ 601556Srgrimesstatic int dump_stab_section_info; /* --stabs */ 611556Srgrimesstatic int do_demangle; /* -C, --demangle */ 621556Srgrimesstatic boolean disassemble; /* -d */ 631556Srgrimesstatic boolean disassemble_all; /* -D */ 6477462Simpstatic int disassemble_zeroes; /* --disassemble-zeroes */ 6577462Simpstatic boolean formats_info; /* -i */ 661556Srgrimesstatic char *only; /* -j secname */ 6796196Sdesstatic int wide_output; /* -w */ 681556Srgrimesstatic bfd_vma start_address = (bfd_vma) -1; /* --start-address */ 691556Srgrimesstatic bfd_vma stop_address = (bfd_vma) -1; /* --stop-address */ 70104549Stjrstatic int dump_debugging; /* --debugging */ 711556Srgrimesstatic bfd_vma adjust_section_vma = 0; /* --adjust-vma */ 721556Srgrimesstatic int file_start_context = 0; /* --file-start-context */ 731556Srgrimes 741556Srgrimes/* Extra info to pass to the disassembler address printing function. */ 751556Srgrimesstruct objdump_disasm_info { 761556Srgrimes bfd *abfd; 771556Srgrimes asection *sec; 781556Srgrimes boolean require_sec; 79101591Sume}; 801556Srgrimes 811556Srgrimes/* Architecture to disassemble for, or default if NULL. */ 821556Srgrimesstatic char *machine = (char *) NULL; 831556Srgrimes 841556Srgrimes/* Target specific options to the disassembler. */ 851556Srgrimesstatic char *disassembler_options = (char *) NULL; 86101591Sume 871556Srgrimes/* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN. */ 8834898Smarkmstatic enum bfd_endian endian = BFD_ENDIAN_UNKNOWN; 89114583Smarkm 9034898Smarkm/* The symbol table. */ 91114583Smarkmstatic asymbol **syms; 92114583Smarkm 931556Srgrimes/* Number of symbols in `syms'. */ 941556Srgrimesstatic long symcount = 0; 951556Srgrimes 9690110Simp/* The sorted symbol table. */ 9790110Simpstatic asymbol **sorted_syms; 9890110Simp 9990110Simp/* Number of symbols in `sorted_syms'. */ 10090110Simpstatic long sorted_symcount = 0; 10190110Simp 10290110Simp/* The dynamic symbol table. */ 1031556Srgrimesstatic asymbol **dynsyms; 1041556Srgrimes 10590110Simp/* Number of symbols in `dynsyms'. */ 1061556Srgrimesstatic long dynsymcount = 0; 1071556Srgrimes 10848560Sbde/* Static declarations. */ 109114583Smarkm 1101556Srgrimesstatic void 11134898Smarkmusage PARAMS ((FILE *, int)); 11234898Smarkm 11334898Smarkmstatic void 11434898Smarkmnonfatal PARAMS ((const char *)); 11534898Smarkm 11634898Smarkmstatic void 11734898Smarkmdisplay_file PARAMS ((char *filename, char *target)); 11834898Smarkm 11934898Smarkmstatic void 12048560Sbdedump_section_header PARAMS ((bfd *, asection *, PTR)); 12134898Smarkm 12234898Smarkmstatic void 12334898Smarkmdump_headers PARAMS ((bfd *)); 12434898Smarkm 12534898Smarkmstatic void 12634898Smarkmdump_data PARAMS ((bfd *abfd)); 1271556Srgrimes 12824348Simpstatic void 1291556Srgrimesdump_relocs PARAMS ((bfd *abfd)); 130101591Sume 131101591Sumestatic void 132101591Sumedump_dynamic_relocs PARAMS ((bfd * abfd)); 133101591Sume 134101591Sumestatic void 135101591Sumedump_reloc_set PARAMS ((bfd *, asection *, arelent **, long)); 136101591Sume 137101591Sumestatic void 1381556Srgrimesdump_symbols PARAMS ((bfd *abfd, boolean dynamic)); 1391556Srgrimes 1401556Srgrimesstatic void 1411556Srgrimesdump_bfd_header PARAMS ((bfd *)); 1421556Srgrimes 1431556Srgrimesstatic void 1441556Srgrimesdump_bfd_private_header PARAMS ((bfd *)); 1451556Srgrimes 1461556Srgrimesstatic void 1471556Srgrimesdisplay_bfd PARAMS ((bfd *abfd)); 1481556Srgrimes 1491556Srgrimesstatic void 1501556Srgrimesdisplay_target_list PARAMS ((void)); 1511556Srgrimes 1521556Srgrimesstatic void 1531556Srgrimesdisplay_info_table PARAMS ((int, int)); 1541556Srgrimes 1551556Srgrimesstatic void 1561556Srgrimesdisplay_target_tables PARAMS ((void)); 1571556Srgrimes 1581556Srgrimesstatic void 1591556Srgrimesdisplay_info PARAMS ((void)); 1601556Srgrimes 1611556Srgrimesstatic void 1621556Srgrimesobjdump_print_value PARAMS ((bfd_vma, struct disassemble_info *, boolean)); 163114583Smarkm 1641556Srgrimesstatic void 165114583Smarkmobjdump_print_symname PARAMS ((bfd *, struct disassemble_info *, asymbol *)); 1661556Srgrimes 1671556Srgrimesstatic asymbol * 1681556Srgrimesfind_symbol_for_address PARAMS ((bfd *, asection *, bfd_vma, boolean, long *)); 1691556Srgrimes 1701556Srgrimesstatic void 1711556Srgrimesobjdump_print_addr_with_sym PARAMS ((bfd *, asection *, asymbol *, bfd_vma, 1721556Srgrimes struct disassemble_info *, boolean)); 1731556Srgrimes 1741556Srgrimesstatic void 1751556Srgrimesobjdump_print_addr PARAMS ((bfd_vma, struct disassemble_info *, boolean)); 1761556Srgrimes 1771556Srgrimesstatic void 1781556Srgrimesobjdump_print_address PARAMS ((bfd_vma, struct disassemble_info *)); 1791556Srgrimes 1801556Srgrimesstatic void 1811556Srgrimesshow_line PARAMS ((bfd *, asection *, bfd_vma)); 1821556Srgrimes 1831556Srgrimesstatic void 1841556Srgrimesdisassemble_bytes PARAMS ((struct disassemble_info *, disassembler_ftype, 1851556Srgrimes boolean, bfd_byte *, bfd_vma, bfd_vma, 1861556Srgrimes arelent ***, arelent **)); 1871556Srgrimes 1881556Srgrimesstatic void 1891556Srgrimesdisassemble_data PARAMS ((bfd *)); 1901556Srgrimes 1911556Srgrimesstatic const char * 1921556Srgrimesendian_string PARAMS ((enum bfd_endian)); 1931556Srgrimes 1941556Srgrimesstatic asymbol ** 1951556Srgrimesslurp_symtab PARAMS ((bfd *)); 1961556Srgrimes 1971556Srgrimesstatic asymbol ** 1981556Srgrimesslurp_dynamic_symtab PARAMS ((bfd *)); 1997165Sjoerg 2001556Srgrimesstatic long 2011556Srgrimesremove_useless_symbols PARAMS ((asymbol **, long)); 2021556Srgrimes 2031556Srgrimesstatic int 2041556Srgrimescompare_symbols PARAMS ((const PTR, const PTR)); 2051556Srgrimes 2061556Srgrimesstatic int 2071556Srgrimescompare_relocs PARAMS ((const PTR, const PTR)); 2081556Srgrimes 2091556Srgrimesstatic void 21090110Simpdump_stabs PARAMS ((bfd *)); 2111556Srgrimes 212121095Smarkmstatic boolean 2131556Srgrimesread_section_stabs PARAMS ((bfd *, const char *, const char *)); 2141556Srgrimes 2151556Srgrimesstatic void 2161556Srgrimesprint_section_stabs PARAMS ((bfd *, const char *, const char *)); 217114583Smarkm 2181556Srgrimesstatic void 2197165Sjoergusage (stream, status) 2201556Srgrimes FILE *stream; 2211556Srgrimes int status; 2221556Srgrimes{ 2231556Srgrimes fprintf (stream, _("Usage: %s OPTION... FILE...\n"), program_name); 2241556Srgrimes fprintf (stream, _("Display information from object FILE.\n")); 2251556Srgrimes fprintf (stream, _("\n At least one of the following switches must be given:\n")); 2261556Srgrimes fprintf (stream, _("\ 2271556Srgrimes -a, --archive-headers Display archive header information\n\ 2281556Srgrimes -f, --file-headers Display the contents of the overall file header\n\ 2291556Srgrimes -p, --private-headers Display object format specific file header contents\n\ 2301556Srgrimes -h, --[section-]headers Display the contents of the section headers\n\ 2311556Srgrimes -x, --all-headers Display the contents of all headers\n\ 2321556Srgrimes -d, --disassemble Display assembler contents of executable sections\n\ 2331556Srgrimes -D, --disassemble-all Display assembler contents of all sections\n\ 2341556Srgrimes -S, --source Intermix source code with disassembly\n\ 2351556Srgrimes -s, --full-contents Display the full contents of all sections requested\n\ 2361556Srgrimes -g, --debugging Display debug information in object file\n\ 237114583Smarkm -G, --stabs Display (in raw form) any STABS info in the file\n\ 2381556Srgrimes -t, --syms Display the contents of the symbol table(s)\n\ 2391556Srgrimes -T, --dynamic-syms Display the contents of the dynamic symbol table\n\ 2401556Srgrimes -r, --reloc Display the relocation entries in the file\n\ 2411556Srgrimes -R, --dynamic-reloc Display the dynamic relocation entries in the file\n\ 2421556Srgrimes -V, --version Display this program's version number\n\ 2431556Srgrimes -i, --info List object formats and architectures supported\n\ 24477491Spirzyk -H, --help Display this information\n\ 24577491Spirzyk")); 2461556Srgrimes if (status != 2) 24777491Spirzyk { 248121095Smarkm fprintf (stream, _("\n The following switches are optional:\n")); 2491556Srgrimes fprintf (stream, _("\ 2501556Srgrimes -b, --target=BFDNAME Specify the target object format as BFDNAME\n\ 2511556Srgrimes -m, --architecture=MACHINE Specify the target architecture as MACHINE\n\ 252121095Smarkm -j, --section=NAME Only display information for section NAME\n\ 253121095Smarkm -M, --disassembler-options=OPT Pass text OPT on to the disassembler\n\ 2541556Srgrimes -EB --endian=big Assume big endian format when disassembling\n\ 255121095Smarkm -EL --endian=little Assume little endian format when disassembling\n\ 2561556Srgrimes --file-start-context Include context from start of file (with -S)\n\ 2571556Srgrimes -l, --line-numbers Include line numbers and filenames in output\n\ 2581556Srgrimes -C, --demangle Decode mangled/processed symbol names\n\ 259121095Smarkm -w, --wide Format output for more than 80 columns\n\ 260121095Smarkm -z, --disassemble-zeroes Do not skip blocks of zeroes when disassembling\n\ 2611556Srgrimes --start-address=ADDR Only process data whoes address is >= ADDR\n\ 2621556Srgrimes --stop-address=ADDR Only process data whoes address is <= ADDR\n\ 2631556Srgrimes --prefix-addresses Print complete address alongside disassembly\n\ 2641556Srgrimes --[no-]show-raw-insn Display hex alongside symbolic disassembly\n\ 265121095Smarkm --adjust-vma=OFFSET Add OFFSET to all displayed section addresses\n\ 266121095Smarkm\n")); 267121095Smarkm list_supported_targets (program_name, stream); 2681556Srgrimes 269105269Smarkm disassembler_usage (stream); 270105269Smarkm } 271105269Smarkm if (status == 0) 272105269Smarkm fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO); 2731556Srgrimes exit (status); 2741556Srgrimes} 275101591Sume 276101591Sume/* 150 isn't special; it's just an arbitrary non-ASCII char value. */ 277101591Sume 278101591Sume#define OPTION_ENDIAN (150) 279101591Sume#define OPTION_START_ADDRESS (OPTION_ENDIAN + 1) 280101591Sume#define OPTION_STOP_ADDRESS (OPTION_START_ADDRESS + 1) 2811556Srgrimes#define OPTION_ADJUST_VMA (OPTION_STOP_ADDRESS + 1) 2821556Srgrimes 2831556Srgrimesstatic struct option long_options[]= 2841556Srgrimes{ 2851556Srgrimes {"adjust-vma", required_argument, NULL, OPTION_ADJUST_VMA}, 2861556Srgrimes {"all-headers", no_argument, NULL, 'x'}, 2871556Srgrimes {"private-headers", no_argument, NULL, 'p'}, 2881556Srgrimes {"architecture", required_argument, NULL, 'm'}, 2891556Srgrimes {"archive-headers", no_argument, NULL, 'a'}, 2901556Srgrimes {"debugging", no_argument, NULL, 'g'}, 2911556Srgrimes {"demangle", no_argument, NULL, 'C'}, 29290110Simp {"disassemble", no_argument, NULL, 'd'}, 2931556Srgrimes {"disassemble-all", no_argument, NULL, 'D'}, 2941556Srgrimes {"disassembler-options", required_argument, NULL, 'M'}, 2951556Srgrimes {"disassemble-zeroes", no_argument, NULL, 'z'}, 2961556Srgrimes {"dynamic-reloc", no_argument, NULL, 'R'}, 2971556Srgrimes {"dynamic-syms", no_argument, NULL, 'T'}, 2981556Srgrimes {"endian", required_argument, NULL, OPTION_ENDIAN}, 2991556Srgrimes {"file-headers", no_argument, NULL, 'f'}, 3001556Srgrimes {"file-start-context", no_argument, &file_start_context, 1}, 3011556Srgrimes {"full-contents", no_argument, NULL, 's'}, 30299744Sdillon {"headers", no_argument, NULL, 'h'}, 3031556Srgrimes {"help", no_argument, NULL, 'H'}, 30431633Swosch {"info", no_argument, NULL, 'i'}, 3051556Srgrimes {"line-numbers", no_argument, NULL, 'l'}, 3061556Srgrimes {"no-show-raw-insn", no_argument, &show_raw_insn, -1}, 3071556Srgrimes {"prefix-addresses", no_argument, &prefix_addresses, 1}, 3081556Srgrimes {"reloc", no_argument, NULL, 'r'}, 3091556Srgrimes {"section", required_argument, NULL, 'j'}, 3101556Srgrimes {"section-headers", no_argument, NULL, 'h'}, 3111556Srgrimes {"show-raw-insn", no_argument, &show_raw_insn, 1}, 3121556Srgrimes {"source", no_argument, NULL, 'S'}, 313114583Smarkm {"stabs", no_argument, NULL, 'G'}, 3141556Srgrimes {"start-address", required_argument, NULL, OPTION_START_ADDRESS}, 3151556Srgrimes {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS}, 3161556Srgrimes {"syms", no_argument, NULL, 't'}, 3171556Srgrimes {"target", required_argument, NULL, 'b'}, 3181556Srgrimes {"version", no_argument, NULL, 'V'}, 3191556Srgrimes {"wide", no_argument, NULL, 'w'}, 3201556Srgrimes {0, no_argument, 0, 0} 3211556Srgrimes}; 32277491Spirzyk 32377491Spirzykstatic void 3241556Srgrimesnonfatal (msg) 32577491Spirzyk const char *msg; 3261556Srgrimes{ 3271556Srgrimes bfd_nonfatal (msg); 3281556Srgrimes exit_status = 1; 32999744Sdillon} 3301556Srgrimes 331105269Smarkmstatic void 332101591Sumedump_section_header (abfd, section, ignored) 3331556Srgrimes bfd *abfd ATTRIBUTE_UNUSED; 3341556Srgrimes asection *section; 3351556Srgrimes PTR ignored ATTRIBUTE_UNUSED; 3361556Srgrimes{ 3371556Srgrimes char *comma = ""; 3381556Srgrimes unsigned int opb = bfd_octets_per_byte (abfd); 339101591Sume 340101591Sume printf ("%3d %-13s %08lx ", section->index, 341101591Sume bfd_get_section_name (abfd, section), 342101591Sume (unsigned long) bfd_section_size (abfd, section) / opb); 343101591Sume printf_vma (bfd_get_section_vma (abfd, section)); 344101591Sume printf (" "); 3451556Srgrimes printf_vma (section->lma); 3461556Srgrimes printf (" %08lx 2**%u", section->filepos, 3471556Srgrimes bfd_get_section_alignment (abfd, section)); 3481556Srgrimes if (! wide_output) 3491556Srgrimes printf ("\n "); 3501556Srgrimes printf (" "); 3511556Srgrimes 3521556Srgrimes#define PF(x, y) \ 35390110Simp if (section->flags & x) { printf ("%s%s", comma, y); comma = ", "; } 3541556Srgrimes 3551556Srgrimes PF (SEC_HAS_CONTENTS, "CONTENTS"); 3561556Srgrimes PF (SEC_ALLOC, "ALLOC"); 3571556Srgrimes PF (SEC_CONSTRUCTOR, "CONSTRUCTOR"); 3581556Srgrimes PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT"); 3591556Srgrimes PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA"); 3601556Srgrimes PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS"); 3611556Srgrimes PF (SEC_LOAD, "LOAD"); 3621556Srgrimes PF (SEC_RELOC, "RELOC"); 36396196Sdes#ifdef SEC_BALIGN 3641556Srgrimes PF (SEC_BALIGN, "BALIGN"); 3651556Srgrimes#endif 3661556Srgrimes PF (SEC_READONLY, "READONLY"); 3671556Srgrimes PF (SEC_CODE, "CODE"); 3681556Srgrimes PF (SEC_DATA, "DATA"); 3691556Srgrimes PF (SEC_ROM, "ROM"); 3701556Srgrimes PF (SEC_DEBUGGING, "DEBUGGING"); 3711556Srgrimes PF (SEC_NEVER_LOAD, "NEVER_LOAD"); 3721556Srgrimes PF (SEC_EXCLUDE, "EXCLUDE"); 3731556Srgrimes PF (SEC_SORT_ENTRIES, "SORT_ENTRIES"); 3741556Srgrimes PF (SEC_SMALL_DATA, "SMALL_DATA"); 3751556Srgrimes PF (SEC_SHARED, "SHARED"); 3761556Srgrimes 3771556Srgrimes if ((section->flags & SEC_LINK_ONCE) != 0) 3781556Srgrimes { 3791556Srgrimes const char *ls; 3801556Srgrimes 3811556Srgrimes switch (section->flags & SEC_LINK_DUPLICATES) 3821556Srgrimes { 3831556Srgrimes default: 3841556Srgrimes abort (); 3851556Srgrimes case SEC_LINK_DUPLICATES_DISCARD: 3861556Srgrimes ls = "LINK_ONCE_DISCARD"; 3871556Srgrimes break; 3881556Srgrimes case SEC_LINK_DUPLICATES_ONE_ONLY: 3891556Srgrimes ls = "LINK_ONCE_ONE_ONLY"; 3901556Srgrimes break; 3911556Srgrimes case SEC_LINK_DUPLICATES_SAME_SIZE: 3921556Srgrimes ls = "LINK_ONCE_SAME_SIZE"; 39338018Sbde break; 39438018Sbde case SEC_LINK_DUPLICATES_SAME_CONTENTS: 3951556Srgrimes ls = "LINK_ONCE_SAME_CONTENTS"; 3961556Srgrimes break; 3971556Srgrimes } 3981556Srgrimes printf ("%s%s", comma, ls); 3991556Srgrimes 400104549Stjr if (section->comdat != NULL) 401104549Stjr printf (" (COMDAT %s %ld)", section->comdat->name, 4021556Srgrimes section->comdat->symbol); 4031556Srgrimes 4041556Srgrimes comma = ", "; 4051556Srgrimes } 406169848Scperciva 407169848Scperciva printf ("\n"); 4081556Srgrimes#undef PF 4091556Srgrimes} 4101556Srgrimes 4111556Srgrimesstatic void 4121556Srgrimesdump_headers (abfd) 4131556Srgrimes bfd *abfd; 4141556Srgrimes{ 4151556Srgrimes printf (_("Sections:\n")); 4161556Srgrimes 4171556Srgrimes#ifndef BFD64 4181556Srgrimes printf (_("Idx Name Size VMA LMA File off Algn")); 4191556Srgrimes#else 4201556Srgrimes printf (_("Idx Name Size VMA LMA File off Algn")); 4211556Srgrimes#endif 4221556Srgrimes 4231556Srgrimes if (wide_output) 4241556Srgrimes printf (_(" Flags")); 4251556Srgrimes printf ("\n"); 4261556Srgrimes 4271556Srgrimes bfd_map_over_sections (abfd, dump_section_header, (PTR) NULL); 4281556Srgrimes} 4291556Srgrimes 4301556Srgrimesstatic asymbol ** 4311556Srgrimesslurp_symtab (abfd) 4321556Srgrimes bfd *abfd; 4331556Srgrimes{ 4341556Srgrimes asymbol **sy = (asymbol **) NULL; 4351556Srgrimes long storage; 4361556Srgrimes 4371556Srgrimes if (!(bfd_get_file_flags (abfd) & HAS_SYMS)) 4381556Srgrimes { 4391556Srgrimes non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); 44090110Simp symcount = 0; 4411556Srgrimes return NULL; 4421556Srgrimes } 4431556Srgrimes 44477462Simp storage = bfd_get_symtab_upper_bound (abfd); 4451556Srgrimes if (storage < 0) 4461556Srgrimes bfd_fatal (bfd_get_filename (abfd)); 4471556Srgrimes 4481556Srgrimes if (storage) 4491556Srgrimes { 4501556Srgrimes sy = (asymbol **) xmalloc (storage); 4511556Srgrimes } 4521556Srgrimes symcount = bfd_canonicalize_symtab (abfd, sy); 4531556Srgrimes if (symcount < 0) 4541556Srgrimes bfd_fatal (bfd_get_filename (abfd)); 4551556Srgrimes if (symcount == 0) 4561556Srgrimes non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); 45738018Sbde return sy; 45838018Sbde} 4591556Srgrimes 4601556Srgrimes/* Read in the dynamic symbols. */ 4611556Srgrimes 4621556Srgrimesstatic asymbol ** 4631556Srgrimesslurp_dynamic_symtab (abfd) 4641556Srgrimes bfd *abfd; 4651556Srgrimes{ 4661556Srgrimes asymbol **sy = (asymbol **) NULL; 4671556Srgrimes long storage; 4681556Srgrimes 4691556Srgrimes storage = bfd_get_dynamic_symtab_upper_bound (abfd); 4701556Srgrimes if (storage < 0) 4711556Srgrimes { 4727165Sjoerg if (!(bfd_get_file_flags (abfd) & DYNAMIC)) 4731556Srgrimes { 4741556Srgrimes non_fatal (_("%s: not a dynamic object"), bfd_get_filename (abfd)); 4751556Srgrimes dynsymcount = 0; 4761556Srgrimes return NULL; 47777462Simp } 4781556Srgrimes 4791556Srgrimes bfd_fatal (bfd_get_filename (abfd)); 4801556Srgrimes } 4811556Srgrimes 4821556Srgrimes if (storage) 4831556Srgrimes { 4841556Srgrimes sy = (asymbol **) xmalloc (storage); 4851556Srgrimes } 4861556Srgrimes dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy); 4871556Srgrimes if (dynsymcount < 0) 4881556Srgrimes bfd_fatal (bfd_get_filename (abfd)); 4891556Srgrimes if (dynsymcount == 0) 4901556Srgrimes non_fatal (_("%s: No dynamic symbols"), bfd_get_filename (abfd)); 49190110Simp return sy; 4921556Srgrimes} 4931556Srgrimes 4941556Srgrimes/* Filter out (in place) symbols that are useless for disassembly. 4951556Srgrimes COUNT is the number of elements in SYMBOLS. 4961556Srgrimes Return the number of useful symbols. */ 4971556Srgrimes 49846057Sdtstatic long 499114509Sobrienremove_useless_symbols (symbols, count) 500114509Sobrien asymbol **symbols; 50146057Sdt long count; 502114583Smarkm{ 503114583Smarkm register asymbol **in_ptr = symbols, **out_ptr = symbols; 5041556Srgrimes 5051556Srgrimes while (--count >= 0) 5061556Srgrimes { 5071556Srgrimes asymbol *sym = *in_ptr++; 5081556Srgrimes 5091556Srgrimes if (sym->name == NULL || sym->name[0] == '\0') 5101556Srgrimes continue; 5111556Srgrimes if (sym->flags & (BSF_DEBUGGING)) 5121556Srgrimes continue; 5131556Srgrimes if (bfd_is_und_section (sym->section) 5141556Srgrimes || bfd_is_com_section (sym->section)) 5151556Srgrimes continue; 5161556Srgrimes 5171556Srgrimes *out_ptr++ = sym; 5181556Srgrimes } 5191556Srgrimes return out_ptr - symbols; 5201556Srgrimes} 5211556Srgrimes 5221556Srgrimes/* Sort symbols into value order. */ 5231556Srgrimes 5241556Srgrimesstatic int 5251556Srgrimescompare_symbols (ap, bp) 5261556Srgrimes const PTR ap; 5271556Srgrimes const PTR bp; 5281556Srgrimes{ 5291556Srgrimes const asymbol *a = *(const asymbol **)ap; 5301556Srgrimes const asymbol *b = *(const asymbol **)bp; 5311556Srgrimes const char *an, *bn; 5321556Srgrimes size_t anl, bnl; 5331556Srgrimes boolean af, bf; 5341556Srgrimes flagword aflags, bflags; 5351556Srgrimes 5361556Srgrimes if (bfd_asymbol_value (a) > bfd_asymbol_value (b)) 5371556Srgrimes return 1; 5381556Srgrimes else if (bfd_asymbol_value (a) < bfd_asymbol_value (b)) 5391556Srgrimes return -1; 5401556Srgrimes 5411556Srgrimes if (a->section > b->section) 5421556Srgrimes return 1; 5431556Srgrimes else if (a->section < b->section) 5441556Srgrimes return -1; 5451556Srgrimes 5461556Srgrimes an = bfd_asymbol_name (a); 5471556Srgrimes bn = bfd_asymbol_name (b); 5481556Srgrimes anl = strlen (an); 5491556Srgrimes bnl = strlen (bn); 5501556Srgrimes 5511556Srgrimes /* The symbols gnu_compiled and gcc2_compiled convey no real 5521556Srgrimes information, so put them after other symbols with the same value. */ 5531556Srgrimes 5541556Srgrimes af = (strstr (an, "gnu_compiled") != NULL 5551556Srgrimes || strstr (an, "gcc2_compiled") != NULL); 5561556Srgrimes bf = (strstr (bn, "gnu_compiled") != NULL 55713978Spst || strstr (bn, "gcc2_compiled") != NULL); 55813978Spst 5591556Srgrimes if (af && ! bf) 56013978Spst return 1; 56113978Spst if (! af && bf) 5621556Srgrimes return -1; 56313978Spst 56413978Spst /* We use a heuristic for the file name, to try to sort it after 5651556Srgrimes more useful symbols. It may not work on non Unix systems, but it 56613978Spst doesn't really matter; the only difference is precisely which 56713978Spst symbol names get printed. */ 5681556Srgrimes 5691556Srgrimes#define file_symbol(s, sn, snl) \ 5701556Srgrimes (((s)->flags & BSF_FILE) != 0 \ 5711556Srgrimes || ((sn)[(snl) - 2] == '.' \ 5721556Srgrimes && ((sn)[(snl) - 1] == 'o' \ 5731556Srgrimes || (sn)[(snl) - 1] == 'a'))) 5741556Srgrimes 5751556Srgrimes af = file_symbol (a, an, anl); 5761556Srgrimes bf = file_symbol (b, bn, bnl); 5771556Srgrimes 5781556Srgrimes if (af && ! bf) 5791556Srgrimes return 1; 5801556Srgrimes if (! af && bf) 5811556Srgrimes return -1; 5821556Srgrimes 5831556Srgrimes /* Try to sort global symbols before local symbols before function 5841556Srgrimes symbols before debugging symbols. */ 5851556Srgrimes 5861556Srgrimes aflags = a->flags; 5871556Srgrimes bflags = b->flags; 5881556Srgrimes 5891556Srgrimes if ((aflags & BSF_DEBUGGING) != (bflags & BSF_DEBUGGING)) 5901556Srgrimes { 5911556Srgrimes if ((aflags & BSF_DEBUGGING) != 0) 5921556Srgrimes return 1; 5931556Srgrimes else 5941556Srgrimes return -1; 5951556Srgrimes } 5961556Srgrimes if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION)) 5971556Srgrimes { 5981556Srgrimes if ((aflags & BSF_FUNCTION) != 0) 5991556Srgrimes return -1; 600104559Scharnier else 601104559Scharnier return 1; 602104559Scharnier } 603104559Scharnier if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL)) 604104559Scharnier { 6051556Srgrimes if ((aflags & BSF_LOCAL) != 0) 606104559Scharnier return 1; 6071556Srgrimes else 608104559Scharnier return -1; 6091556Srgrimes } 6101556Srgrimes if ((aflags & BSF_GLOBAL) != (bflags & BSF_GLOBAL)) 6111556Srgrimes { 6121556Srgrimes if ((aflags & BSF_GLOBAL) != 0) 6131556Srgrimes return -1; 6141556Srgrimes else 6151556Srgrimes return 1; 6161556Srgrimes } 6171556Srgrimes 6181556Srgrimes /* Symbols that start with '.' might be section names, so sort them 6191556Srgrimes after symbols that don't start with '.'. */ 6201556Srgrimes if (an[0] == '.' && bn[0] != '.') 6211556Srgrimes return 1; 6221556Srgrimes if (an[0] != '.' && bn[0] == '.') 6231556Srgrimes return -1; 6241556Srgrimes 6251556Srgrimes /* Finally, if we can't distinguish them in any other way, try to 6261556Srgrimes get consistent results by sorting the symbols by name. */ 6271556Srgrimes return strcmp (an, bn); 6281556Srgrimes} 6291556Srgrimes 6301556Srgrimes/* Sort relocs into address order. */ 6311556Srgrimes 6321556Srgrimesstatic int 6331556Srgrimescompare_relocs (ap, bp) 6341556Srgrimes const PTR ap; 6351556Srgrimes const PTR bp; 6361556Srgrimes{ 6371556Srgrimes const arelent *a = *(const arelent **)ap; 6381556Srgrimes const arelent *b = *(const arelent **)bp; 6391556Srgrimes 6401556Srgrimes if (a->address > b->address) 6411556Srgrimes return 1; 6421556Srgrimes else if (a->address < b->address) 6431556Srgrimes return -1; 6441556Srgrimes 6451556Srgrimes /* So that associated relocations tied to the same address show up 6461556Srgrimes in the correct order, we don't do any further sorting. */ 6471556Srgrimes if (a > b) 6481556Srgrimes return 1; 6491556Srgrimes else if (a < b) 6501556Srgrimes return -1; 6511556Srgrimes else 6521556Srgrimes return 0; 6531556Srgrimes} 6541556Srgrimes 6551556Srgrimes/* Print VMA to STREAM. If SKIP_ZEROES is true, omit leading zeroes. */ 6561556Srgrimes 6571556Srgrimesstatic void 6581556Srgrimesobjdump_print_value (vma, info, skip_zeroes) 6591556Srgrimes bfd_vma vma; 6601556Srgrimes struct disassemble_info *info; 6611556Srgrimes boolean skip_zeroes; 6621556Srgrimes{ 6631556Srgrimes char buf[30]; 6641556Srgrimes char *p; 6651556Srgrimes 6661556Srgrimes sprintf_vma (buf, vma); 6671556Srgrimes if (! skip_zeroes) 6681556Srgrimes p = buf; 6691556Srgrimes else 6701556Srgrimes { 671114583Smarkm for (p = buf; *p == '0'; ++p) 6721556Srgrimes ; 6738855Srgrimes if (*p == '\0') 6741556Srgrimes --p; 6751556Srgrimes } 6761556Srgrimes (*info->fprintf_func) (info->stream, "%s", p); 6771556Srgrimes} 6781556Srgrimes 6791556Srgrimes/* Print the name of a symbol. */ 6801556Srgrimes 681114583Smarkmstatic void 6821556Srgrimesobjdump_print_symname (abfd, info, sym) 6838855Srgrimes bfd *abfd; 6841556Srgrimes struct disassemble_info *info; 6851556Srgrimes asymbol *sym; 6861556Srgrimes{ 6871556Srgrimes char *alloc; 6881556Srgrimes const char *name; 6891556Srgrimes const char *print; 6901556Srgrimes 6911556Srgrimes alloc = NULL; 6921556Srgrimes name = bfd_asymbol_name (sym); 6931556Srgrimes if (! do_demangle || name[0] == '\0') 6941556Srgrimes print = name; 6951556Srgrimes else 6961556Srgrimes { 6971556Srgrimes /* Demangle the name. */ 6981556Srgrimes if (bfd_get_symbol_leading_char (abfd) == name[0]) 6991556Srgrimes ++name; 7001556Srgrimes 7011556Srgrimes alloc = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS); 7021556Srgrimes if (alloc == NULL) 7031556Srgrimes print = name; 7041556Srgrimes else 7051556Srgrimes print = alloc; 7061556Srgrimes } 7071556Srgrimes 7081556Srgrimes if (info != NULL) 7091556Srgrimes (*info->fprintf_func) (info->stream, "%s", print); 7101556Srgrimes else 7111556Srgrimes printf ("%s", print); 7121556Srgrimes 7131556Srgrimes if (alloc != NULL) 7141556Srgrimes free (alloc); 7151556Srgrimes} 7161556Srgrimes 7171556Srgrimes/* Locate a symbol given a bfd, a section, and a VMA. If REQUIRE_SEC 7181556Srgrimes is true, then always require the symbol to be in the section. This 7191556Srgrimes returns NULL if there is no suitable symbol. If PLACE is not NULL, 7201556Srgrimes then *PLACE is set to the index of the symbol in sorted_syms. */ 7211556Srgrimes 7221556Srgrimesstatic asymbol * 7231556Srgrimesfind_symbol_for_address (abfd, sec, vma, require_sec, place) 7241556Srgrimes bfd *abfd; 7251556Srgrimes asection *sec; 7261556Srgrimes bfd_vma vma; 72790110Simp boolean require_sec; 7281556Srgrimes long *place; 7291556Srgrimes{ 7301556Srgrimes /* @@ Would it speed things up to cache the last two symbols returned, 7311556Srgrimes and maybe their address ranges? For many processors, only one memory 7321556Srgrimes operand can be present at a time, so the 2-entry cache wouldn't be 7331556Srgrimes constantly churned by code doing heavy memory accesses. */ 7341556Srgrimes 7351556Srgrimes /* Indices in `sorted_syms'. */ 7361556Srgrimes long min = 0; 7371556Srgrimes long max = sorted_symcount; 7381556Srgrimes long thisplace; 7391556Srgrimes unsigned int opb = bfd_octets_per_byte (abfd); 7401556Srgrimes 7411556Srgrimes if (sorted_symcount < 1) 7421556Srgrimes return NULL; 7431556Srgrimes 7441556Srgrimes /* Perform a binary search looking for the closest symbol to the 7451556Srgrimes required value. We are searching the range (min, max]. */ 7461556Srgrimes while (min + 1 < max) 7471556Srgrimes { 7481556Srgrimes asymbol *sym; 7491556Srgrimes 7501556Srgrimes thisplace = (max + min) / 2; 7511556Srgrimes sym = sorted_syms[thisplace]; 7521556Srgrimes 7531556Srgrimes if (bfd_asymbol_value (sym) > vma) 7541556Srgrimes max = thisplace; 7551556Srgrimes else if (bfd_asymbol_value (sym) < vma) 7561556Srgrimes min = thisplace; 7571556Srgrimes else 7581556Srgrimes { 7591556Srgrimes min = thisplace; 76090110Simp break; 7611556Srgrimes } 76226466Scharnier } 763141578Sru 764141578Sru /* The symbol we want is now in min, the low end of the range we 7651556Srgrimes were searching. If there are several symbols with the same 7661556Srgrimes value, we want the first one. */ 7671556Srgrimes thisplace = min; 7681556Srgrimes while (thisplace > 0 7691556Srgrimes && (bfd_asymbol_value (sorted_syms[thisplace]) 7701556Srgrimes == bfd_asymbol_value (sorted_syms[thisplace - 1]))) 7711556Srgrimes --thisplace; 7721556Srgrimes 7731556Srgrimes /* If the file is relocateable, and the symbol could be from this 7741556Srgrimes section, prefer a symbol from this section over symbols from 7751556Srgrimes others, even if the other symbol's value might be closer. 7761556Srgrimes 7771556Srgrimes Note that this may be wrong for some symbol references if the 7781556Srgrimes sections have overlapping memory ranges, but in that case there's 7791556Srgrimes no way to tell what's desired without looking at the relocation 7801556Srgrimes table. */ 781104563Stjr 7821556Srgrimes if (sorted_syms[thisplace]->section != sec 783104563Stjr && (require_sec 7841556Srgrimes || ((abfd->flags & HAS_RELOC) != 0 7851556Srgrimes && vma >= bfd_get_section_vma (abfd, sec) 7861556Srgrimes && vma < (bfd_get_section_vma (abfd, sec) 787104563Stjr + bfd_section_size (abfd, sec) / opb)))) 788104563Stjr { 7891556Srgrimes long i; 790104563Stjr 791104563Stjr for (i = thisplace + 1; i < sorted_symcount; i++) 7921556Srgrimes { 7931556Srgrimes if (bfd_asymbol_value (sorted_syms[i]) 7941556Srgrimes != bfd_asymbol_value (sorted_syms[thisplace])) 795 break; 796 } 797 --i; 798 for (; i >= 0; i--) 799 { 800 if (sorted_syms[i]->section == sec 801 && (i == 0 802 || sorted_syms[i - 1]->section != sec 803 || (bfd_asymbol_value (sorted_syms[i]) 804 != bfd_asymbol_value (sorted_syms[i - 1])))) 805 { 806 thisplace = i; 807 break; 808 } 809 } 810 811 if (sorted_syms[thisplace]->section != sec) 812 { 813 /* We didn't find a good symbol with a smaller value. 814 Look for one with a larger value. */ 815 for (i = thisplace + 1; i < sorted_symcount; i++) 816 { 817 if (sorted_syms[i]->section == sec) 818 { 819 thisplace = i; 820 break; 821 } 822 } 823 } 824 825 if (sorted_syms[thisplace]->section != sec 826 && (require_sec 827 || ((abfd->flags & HAS_RELOC) != 0 828 && vma >= bfd_get_section_vma (abfd, sec) 829 && vma < (bfd_get_section_vma (abfd, sec) 830 + bfd_section_size (abfd, sec))))) 831 { 832 /* There is no suitable symbol. */ 833 return NULL; 834 } 835 } 836 837 if (place != NULL) 838 *place = thisplace; 839 840 return sorted_syms[thisplace]; 841} 842 843/* Print an address to INFO symbolically. */ 844 845static void 846objdump_print_addr_with_sym (abfd, sec, sym, vma, info, skip_zeroes) 847 bfd *abfd; 848 asection *sec; 849 asymbol *sym; 850 bfd_vma vma; 851 struct disassemble_info *info; 852 boolean skip_zeroes; 853{ 854 objdump_print_value (vma, info, skip_zeroes); 855 856 if (sym == NULL) 857 { 858 bfd_vma secaddr; 859 860 (*info->fprintf_func) (info->stream, " <%s", 861 bfd_get_section_name (abfd, sec)); 862 secaddr = bfd_get_section_vma (abfd, sec); 863 if (vma < secaddr) 864 { 865 (*info->fprintf_func) (info->stream, "-0x"); 866 objdump_print_value (secaddr - vma, info, true); 867 } 868 else if (vma > secaddr) 869 { 870 (*info->fprintf_func) (info->stream, "+0x"); 871 objdump_print_value (vma - secaddr, info, true); 872 } 873 (*info->fprintf_func) (info->stream, ">"); 874 } 875 else 876 { 877 (*info->fprintf_func) (info->stream, " <"); 878 objdump_print_symname (abfd, info, sym); 879 if (bfd_asymbol_value (sym) > vma) 880 { 881 (*info->fprintf_func) (info->stream, "-0x"); 882 objdump_print_value (bfd_asymbol_value (sym) - vma, info, true); 883 } 884 else if (vma > bfd_asymbol_value (sym)) 885 { 886 (*info->fprintf_func) (info->stream, "+0x"); 887 objdump_print_value (vma - bfd_asymbol_value (sym), info, true); 888 } 889 (*info->fprintf_func) (info->stream, ">"); 890 } 891} 892 893/* Print VMA to INFO, symbolically if possible. If SKIP_ZEROES is 894 true, don't output leading zeroes. */ 895 896static void 897objdump_print_addr (vma, info, skip_zeroes) 898 bfd_vma vma; 899 struct disassemble_info *info; 900 boolean skip_zeroes; 901{ 902 struct objdump_disasm_info *aux; 903 asymbol *sym; 904 905 if (sorted_symcount < 1) 906 { 907 (*info->fprintf_func) (info->stream, "0x"); 908 objdump_print_value (vma, info, skip_zeroes); 909 return; 910 } 911 912 aux = (struct objdump_disasm_info *) info->application_data; 913 sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec, 914 (long *) NULL); 915 objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info, 916 skip_zeroes); 917} 918 919/* Print VMA to INFO. This function is passed to the disassembler 920 routine. */ 921 922static void 923objdump_print_address (vma, info) 924 bfd_vma vma; 925 struct disassemble_info *info; 926{ 927 objdump_print_addr (vma, info, ! prefix_addresses); 928} 929 930/* Determine of the given address has a symbol associated with it. */ 931 932static int 933objdump_symbol_at_address (vma, info) 934 bfd_vma vma; 935 struct disassemble_info * info; 936{ 937 struct objdump_disasm_info * aux; 938 asymbol * sym; 939 940 /* No symbols - do not bother checking. */ 941 if (sorted_symcount < 1) 942 return 0; 943 944 aux = (struct objdump_disasm_info *) info->application_data; 945 sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec, 946 (long *) NULL); 947 948 return (sym != NULL && (bfd_asymbol_value (sym) == vma)); 949} 950 951/* Hold the last function name and the last line number we displayed 952 in a disassembly. */ 953 954static char *prev_functionname; 955static unsigned int prev_line; 956 957/* We keep a list of all files that we have seen when doing a 958 dissassembly with source, so that we know how much of the file to 959 display. This can be important for inlined functions. */ 960 961struct print_file_list 962{ 963 struct print_file_list *next; 964 char *filename; 965 unsigned int line; 966 FILE *f; 967}; 968 969static struct print_file_list *print_files; 970 971/* The number of preceding context lines to show when we start 972 displaying a file for the first time. */ 973 974#define SHOW_PRECEDING_CONTEXT_LINES (5) 975 976/* Skip ahead to a given line in a file, optionally printing each 977 line. */ 978 979static void 980skip_to_line PARAMS ((struct print_file_list *, unsigned int, boolean)); 981 982static void 983skip_to_line (p, line, show) 984 struct print_file_list *p; 985 unsigned int line; 986 boolean show; 987{ 988 while (p->line < line) 989 { 990 char buf[100]; 991 992 if (fgets (buf, sizeof buf, p->f) == NULL) 993 { 994 fclose (p->f); 995 p->f = NULL; 996 break; 997 } 998 999 if (show) 1000 printf ("%s", buf); 1001 1002 if (strchr (buf, '\n') != NULL) 1003 ++p->line; 1004 } 1005} 1006 1007/* Show the line number, or the source line, in a dissassembly 1008 listing. */ 1009 1010static void 1011show_line (abfd, section, addr_offset) 1012 bfd *abfd; 1013 asection *section; 1014 bfd_vma addr_offset; 1015{ 1016 CONST char *filename; 1017 CONST char *functionname; 1018 unsigned int line; 1019 1020 if (! with_line_numbers && ! with_source_code) 1021 return; 1022 1023 if (! bfd_find_nearest_line (abfd, section, syms, addr_offset, &filename, 1024 &functionname, &line)) 1025 return; 1026 1027 if (filename != NULL && *filename == '\0') 1028 filename = NULL; 1029 if (functionname != NULL && *functionname == '\0') 1030 functionname = NULL; 1031 1032 if (with_line_numbers) 1033 { 1034 if (functionname != NULL 1035 && (prev_functionname == NULL 1036 || strcmp (functionname, prev_functionname) != 0)) 1037 printf ("%s():\n", functionname); 1038 if (line > 0 && line != prev_line) 1039 printf ("%s:%u\n", filename == NULL ? "???" : filename, line); 1040 } 1041 1042 if (with_source_code 1043 && filename != NULL 1044 && line > 0) 1045 { 1046 struct print_file_list **pp, *p; 1047 1048 for (pp = &print_files; *pp != NULL; pp = &(*pp)->next) 1049 if (strcmp ((*pp)->filename, filename) == 0) 1050 break; 1051 p = *pp; 1052 1053 if (p != NULL) 1054 { 1055 if (p != print_files) 1056 { 1057 int l; 1058 1059 /* We have reencountered a file name which we saw 1060 earlier. This implies that either we are dumping out 1061 code from an included file, or the same file was 1062 linked in more than once. There are two common cases 1063 of an included file: inline functions in a header 1064 file, and a bison or flex skeleton file. In the 1065 former case we want to just start printing (but we 1066 back up a few lines to give context); in the latter 1067 case we want to continue from where we left off. I 1068 can't think of a good way to distinguish the cases, 1069 so I used a heuristic based on the file name. */ 1070 if (strcmp (p->filename + strlen (p->filename) - 2, ".h") != 0) 1071 l = p->line; 1072 else 1073 { 1074 l = line - SHOW_PRECEDING_CONTEXT_LINES; 1075 if (l < 0) 1076 l = 0; 1077 } 1078 1079 if (p->f == NULL) 1080 { 1081 p->f = fopen (p->filename, "r"); 1082 p->line = 0; 1083 } 1084 if (p->f != NULL) 1085 skip_to_line (p, l, false); 1086 1087 if (print_files->f != NULL) 1088 { 1089 fclose (print_files->f); 1090 print_files->f = NULL; 1091 } 1092 } 1093 1094 if (p->f != NULL) 1095 { 1096 skip_to_line (p, line, true); 1097 *pp = p->next; 1098 p->next = print_files; 1099 print_files = p; 1100 } 1101 } 1102 else 1103 { 1104 FILE *f; 1105 1106 f = fopen (filename, "r"); 1107 if (f != NULL) 1108 { 1109 int l; 1110 1111 p = ((struct print_file_list *) 1112 xmalloc (sizeof (struct print_file_list))); 1113 p->filename = xmalloc (strlen (filename) + 1); 1114 strcpy (p->filename, filename); 1115 p->line = 0; 1116 p->f = f; 1117 1118 if (print_files != NULL && print_files->f != NULL) 1119 { 1120 fclose (print_files->f); 1121 print_files->f = NULL; 1122 } 1123 p->next = print_files; 1124 print_files = p; 1125 1126 if (file_start_context) 1127 l = 0; 1128 else 1129 l = line - SHOW_PRECEDING_CONTEXT_LINES; 1130 if (l < 0) 1131 l = 0; 1132 skip_to_line (p, l, false); 1133 if (p->f != NULL) 1134 skip_to_line (p, line, true); 1135 } 1136 } 1137 } 1138 1139 if (functionname != NULL 1140 && (prev_functionname == NULL 1141 || strcmp (functionname, prev_functionname) != 0)) 1142 { 1143 if (prev_functionname != NULL) 1144 free (prev_functionname); 1145 prev_functionname = xmalloc (strlen (functionname) + 1); 1146 strcpy (prev_functionname, functionname); 1147 } 1148 1149 if (line > 0 && line != prev_line) 1150 prev_line = line; 1151} 1152 1153/* Pseudo FILE object for strings. */ 1154typedef struct 1155{ 1156 char *buffer; 1157 size_t size; 1158 char *current; 1159} SFILE; 1160 1161/* sprintf to a "stream" */ 1162 1163static int 1164#ifdef ANSI_PROTOTYPES 1165objdump_sprintf (SFILE *f, const char *format, ...) 1166#else 1167objdump_sprintf (va_alist) 1168 va_dcl 1169#endif 1170{ 1171#ifndef ANSI_PROTOTYPES 1172 SFILE *f; 1173 const char *format; 1174#endif 1175 char *buf; 1176 va_list args; 1177 size_t n; 1178 1179#ifdef ANSI_PROTOTYPES 1180 va_start (args, format); 1181#else 1182 va_start (args); 1183 f = va_arg (args, SFILE *); 1184 format = va_arg (args, const char *); 1185#endif 1186 1187 vasprintf (&buf, format, args); 1188 1189 va_end (args); 1190 1191 if (buf == NULL) 1192 { 1193 fatal (_("Out of virtual memory")); 1194 } 1195 1196 n = strlen (buf); 1197 1198 while ((size_t) ((f->buffer + f->size) - f->current) < n + 1) 1199 { 1200 size_t curroff; 1201 1202 curroff = f->current - f->buffer; 1203 f->size *= 2; 1204 f->buffer = xrealloc (f->buffer, f->size); 1205 f->current = f->buffer + curroff; 1206 } 1207 1208 memcpy (f->current, buf, n); 1209 f->current += n; 1210 f->current[0] = '\0'; 1211 1212 free (buf); 1213 1214 return n; 1215} 1216 1217/* The number of zeroes we want to see before we start skipping them. 1218 The number is arbitrarily chosen. */ 1219 1220#define SKIP_ZEROES (8) 1221 1222/* The number of zeroes to skip at the end of a section. If the 1223 number of zeroes at the end is between SKIP_ZEROES_AT_END and 1224 SKIP_ZEROES, they will be disassembled. If there are fewer than 1225 SKIP_ZEROES_AT_END, they will be skipped. This is a heuristic 1226 attempt to avoid disassembling zeroes inserted by section 1227 alignment. */ 1228 1229#define SKIP_ZEROES_AT_END (3) 1230 1231/* Disassemble some data in memory between given values. */ 1232 1233static void 1234disassemble_bytes (info, disassemble_fn, insns, data, 1235 start_offset, stop_offset, relppp, 1236 relppend) 1237 struct disassemble_info *info; 1238 disassembler_ftype disassemble_fn; 1239 boolean insns; 1240 bfd_byte *data; 1241 bfd_vma start_offset; 1242 bfd_vma stop_offset; 1243 arelent ***relppp; 1244 arelent **relppend; 1245{ 1246 struct objdump_disasm_info *aux; 1247 asection *section; 1248 int octets_per_line; 1249 boolean done_dot; 1250 int skip_addr_chars; 1251 bfd_vma addr_offset; 1252 int opb = info->octets_per_byte; 1253 1254 aux = (struct objdump_disasm_info *) info->application_data; 1255 section = aux->sec; 1256 1257 if (insns) 1258 octets_per_line = 4; 1259 else 1260 octets_per_line = 16; 1261 1262 /* Figure out how many characters to skip at the start of an 1263 address, to make the disassembly look nicer. We discard leading 1264 zeroes in chunks of 4, ensuring that there is always a leading 1265 zero remaining. */ 1266 skip_addr_chars = 0; 1267 if (! prefix_addresses) 1268 { 1269 char buf[30]; 1270 char *s; 1271 1272 sprintf_vma (buf, section->vma + 1273 bfd_section_size (section->owner, section) / opb); 1274 s = buf; 1275 while (s[0] == '0' && s[1] == '0' && s[2] == '0' && s[3] == '0' 1276 && s[4] == '0') 1277 { 1278 skip_addr_chars += 4; 1279 s += 4; 1280 } 1281 } 1282 1283 info->insn_info_valid = 0; 1284 1285 done_dot = false; 1286 addr_offset = start_offset; 1287 while (addr_offset < stop_offset) 1288 { 1289 bfd_vma z; 1290 int octets = 0; 1291 boolean need_nl = false; 1292 1293 /* If we see more than SKIP_ZEROES octets of zeroes, we just 1294 print `...'. */ 1295 for (z = addr_offset * opb; z < stop_offset * opb; z++) 1296 if (data[z] != 0) 1297 break; 1298 if (! disassemble_zeroes 1299 && (info->insn_info_valid == 0 1300 || info->branch_delay_insns == 0) 1301 && (z - addr_offset * opb >= SKIP_ZEROES 1302 || (z == stop_offset * opb && 1303 z - addr_offset * opb < SKIP_ZEROES_AT_END))) 1304 { 1305 printf ("\t...\n"); 1306 1307 /* If there are more nonzero octets to follow, we only skip 1308 zeroes in multiples of 4, to try to avoid running over 1309 the start of an instruction which happens to start with 1310 zero. */ 1311 if (z != stop_offset * opb) 1312 z = addr_offset * opb + ((z - addr_offset * opb) &~ 3); 1313 1314 octets = z - addr_offset * opb; 1315 } 1316 else 1317 { 1318 char buf[50]; 1319 SFILE sfile; 1320 int bpc = 0; 1321 int pb = 0; 1322 1323 done_dot = false; 1324 1325 if (with_line_numbers || with_source_code) 1326 show_line (aux->abfd, section, addr_offset); 1327 1328 if (! prefix_addresses) 1329 { 1330 char *s; 1331 1332 sprintf_vma (buf, section->vma + addr_offset); 1333 for (s = buf + skip_addr_chars; *s == '0'; s++) 1334 *s = ' '; 1335 if (*s == '\0') 1336 *--s = '0'; 1337 printf ("%s:\t", buf + skip_addr_chars); 1338 } 1339 else 1340 { 1341 aux->require_sec = true; 1342 objdump_print_address (section->vma + addr_offset, info); 1343 aux->require_sec = false; 1344 putchar (' '); 1345 } 1346 1347 if (insns) 1348 { 1349 sfile.size = 120; 1350 sfile.buffer = xmalloc (sfile.size); 1351 sfile.current = sfile.buffer; 1352 info->fprintf_func = (fprintf_ftype) objdump_sprintf; 1353 info->stream = (FILE *) &sfile; 1354 info->bytes_per_line = 0; 1355 info->bytes_per_chunk = 0; 1356 1357 /* FIXME: This is wrong. It tests the number of octets 1358 in the last instruction, not the current one. */ 1359 if (*relppp < relppend 1360 && (**relppp)->address >= addr_offset 1361 && (**relppp)->address < addr_offset + octets / opb) 1362 info->flags = INSN_HAS_RELOC; 1363 else 1364 info->flags = 0; 1365 1366 octets = (*disassemble_fn) (section->vma + addr_offset, info); 1367 info->fprintf_func = (fprintf_ftype) fprintf; 1368 info->stream = stdout; 1369 if (info->bytes_per_line != 0) 1370 octets_per_line = info->bytes_per_line; 1371 if (octets < 0) 1372 { 1373 if (sfile.current != sfile.buffer) 1374 printf ("%s\n", sfile.buffer); 1375 free (sfile.buffer); 1376 break; 1377 } 1378 } 1379 else 1380 { 1381 bfd_vma j; 1382 1383 octets = octets_per_line; 1384 if (addr_offset + octets / opb > stop_offset) 1385 octets = (stop_offset - addr_offset) * opb; 1386 1387 for (j = addr_offset * opb; j < addr_offset * opb + octets; ++j) 1388 { 1389 if (isprint (data[j])) 1390 buf[j - addr_offset * opb] = data[j]; 1391 else 1392 buf[j - addr_offset * opb] = '.'; 1393 } 1394 buf[j - addr_offset * opb] = '\0'; 1395 } 1396 1397 if (prefix_addresses 1398 ? show_raw_insn > 0 1399 : show_raw_insn >= 0) 1400 { 1401 bfd_vma j; 1402 1403 /* If ! prefix_addresses and ! wide_output, we print 1404 octets_per_line octets per line. */ 1405 pb = octets; 1406 if (pb > octets_per_line && ! prefix_addresses && ! wide_output) 1407 pb = octets_per_line; 1408 1409 if (info->bytes_per_chunk) 1410 bpc = info->bytes_per_chunk; 1411 else 1412 bpc = 1; 1413 1414 for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc) 1415 { 1416 int k; 1417 if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE) 1418 { 1419 for (k = bpc - 1; k >= 0; k--) 1420 printf ("%02x", (unsigned) data[j + k]); 1421 putchar (' '); 1422 } 1423 else 1424 { 1425 for (k = 0; k < bpc; k++) 1426 printf ("%02x", (unsigned) data[j + k]); 1427 putchar (' '); 1428 } 1429 } 1430 1431 for (; pb < octets_per_line; pb += bpc) 1432 { 1433 int k; 1434 1435 for (k = 0; k < bpc; k++) 1436 printf (" "); 1437 putchar (' '); 1438 } 1439 1440 /* Separate raw data from instruction by extra space. */ 1441 if (insns) 1442 putchar ('\t'); 1443 else 1444 printf (" "); 1445 } 1446 1447 if (! insns) 1448 printf ("%s", buf); 1449 else 1450 { 1451 printf ("%s", sfile.buffer); 1452 free (sfile.buffer); 1453 } 1454 1455 if (prefix_addresses 1456 ? show_raw_insn > 0 1457 : show_raw_insn >= 0) 1458 { 1459 while (pb < octets) 1460 { 1461 bfd_vma j; 1462 char *s; 1463 1464 putchar ('\n'); 1465 j = addr_offset * opb + pb; 1466 1467 sprintf_vma (buf, section->vma + j / opb); 1468 for (s = buf + skip_addr_chars; *s == '0'; s++) 1469 *s = ' '; 1470 if (*s == '\0') 1471 *--s = '0'; 1472 printf ("%s:\t", buf + skip_addr_chars); 1473 1474 pb += octets_per_line; 1475 if (pb > octets) 1476 pb = octets; 1477 for (; j < addr_offset * opb + pb; j += bpc) 1478 { 1479 int k; 1480 1481 if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE) 1482 { 1483 for (k = bpc - 1; k >= 0; k--) 1484 printf ("%02x", (unsigned) data[j + k]); 1485 putchar (' '); 1486 } 1487 else 1488 { 1489 for (k = 0; k < bpc; k++) 1490 printf ("%02x", (unsigned) data[j + k]); 1491 putchar (' '); 1492 } 1493 } 1494 } 1495 } 1496 1497 if (!wide_output) 1498 putchar ('\n'); 1499 else 1500 need_nl = true; 1501 } 1502 1503 if (dump_reloc_info 1504 && (section->flags & SEC_RELOC) != 0) 1505 { 1506 while ((*relppp) < relppend 1507 && ((**relppp)->address >= (bfd_vma) addr_offset 1508 && (**relppp)->address < (bfd_vma) addr_offset + octets / opb)) 1509 { 1510 arelent *q; 1511 1512 q = **relppp; 1513 1514 if (wide_output) 1515 putchar ('\t'); 1516 else 1517 printf ("\t\t\t"); 1518 1519 objdump_print_value (section->vma + q->address, info, true); 1520 1521 printf (": %s\t", q->howto->name); 1522 1523 if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL) 1524 printf ("*unknown*"); 1525 else 1526 { 1527 const char *sym_name; 1528 1529 sym_name = bfd_asymbol_name (*q->sym_ptr_ptr); 1530 if (sym_name != NULL && *sym_name != '\0') 1531 objdump_print_symname (aux->abfd, info, *q->sym_ptr_ptr); 1532 else 1533 { 1534 asection *sym_sec; 1535 1536 sym_sec = bfd_get_section (*q->sym_ptr_ptr); 1537 sym_name = bfd_get_section_name (aux->abfd, sym_sec); 1538 if (sym_name == NULL || *sym_name == '\0') 1539 sym_name = "*unknown*"; 1540 printf ("%s", sym_name); 1541 } 1542 } 1543 1544 if (q->addend) 1545 { 1546 printf ("+0x"); 1547 objdump_print_value (q->addend, info, true); 1548 } 1549 1550 printf ("\n"); 1551 need_nl = false; 1552 ++(*relppp); 1553 } 1554 } 1555 1556 if (need_nl) 1557 printf ("\n"); 1558 1559 addr_offset += octets / opb; 1560 } 1561} 1562 1563/* Disassemble the contents of an object file. */ 1564 1565static void 1566disassemble_data (abfd) 1567 bfd *abfd; 1568{ 1569 unsigned long addr_offset; 1570 disassembler_ftype disassemble_fn; 1571 struct disassemble_info disasm_info; 1572 struct objdump_disasm_info aux; 1573 asection *section; 1574 unsigned int opb; 1575 1576 print_files = NULL; 1577 prev_functionname = NULL; 1578 prev_line = -1; 1579 1580 /* We make a copy of syms to sort. We don't want to sort syms 1581 because that will screw up the relocs. */ 1582 sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *)); 1583 memcpy (sorted_syms, syms, symcount * sizeof (asymbol *)); 1584 1585 sorted_symcount = remove_useless_symbols (sorted_syms, symcount); 1586 1587 /* Sort the symbols into section and symbol order */ 1588 qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols); 1589 1590 INIT_DISASSEMBLE_INFO(disasm_info, stdout, fprintf); 1591 disasm_info.application_data = (PTR) &aux; 1592 aux.abfd = abfd; 1593 aux.require_sec = false; 1594 disasm_info.print_address_func = objdump_print_address; 1595 disasm_info.symbol_at_address_func = objdump_symbol_at_address; 1596 1597 if (machine != (char *) NULL) 1598 { 1599 const bfd_arch_info_type *info = bfd_scan_arch (machine); 1600 if (info == NULL) 1601 { 1602 fatal (_("Can't use supplied machine %s"), machine); 1603 } 1604 abfd->arch_info = info; 1605 } 1606 1607 if (endian != BFD_ENDIAN_UNKNOWN) 1608 { 1609 struct bfd_target *xvec; 1610 1611 xvec = (struct bfd_target *) xmalloc (sizeof (struct bfd_target)); 1612 memcpy (xvec, abfd->xvec, sizeof (struct bfd_target)); 1613 xvec->byteorder = endian; 1614 abfd->xvec = xvec; 1615 } 1616 1617 disassemble_fn = disassembler (abfd); 1618 if (!disassemble_fn) 1619 { 1620 non_fatal (_("Can't disassemble for architecture %s\n"), 1621 bfd_printable_arch_mach (bfd_get_arch (abfd), 0)); 1622 exit_status = 1; 1623 return; 1624 } 1625 1626 opb = bfd_octets_per_byte (abfd); 1627 1628 disasm_info.flavour = bfd_get_flavour (abfd); 1629 disasm_info.arch = bfd_get_arch (abfd); 1630 disasm_info.mach = bfd_get_mach (abfd); 1631 disasm_info.disassembler_options = disassembler_options; 1632 disasm_info.octets_per_byte = opb; 1633 1634 if (bfd_big_endian (abfd)) 1635 disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG; 1636 else if (bfd_little_endian (abfd)) 1637 disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE; 1638 else 1639 /* ??? Aborting here seems too drastic. We could default to big or little 1640 instead. */ 1641 disasm_info.endian = BFD_ENDIAN_UNKNOWN; 1642 1643 for (section = abfd->sections; 1644 section != (asection *) NULL; 1645 section = section->next) 1646 { 1647 bfd_byte *data = NULL; 1648 bfd_size_type datasize = 0; 1649 arelent **relbuf = NULL; 1650 arelent **relpp = NULL; 1651 arelent **relppend = NULL; 1652 unsigned long stop_offset; 1653 asymbol *sym = NULL; 1654 long place = 0; 1655 1656 if ((section->flags & SEC_LOAD) == 0 1657 || (! disassemble_all 1658 && only == NULL 1659 && (section->flags & SEC_CODE) == 0)) 1660 continue; 1661 if (only != (char *) NULL && strcmp (only, section->name) != 0) 1662 continue; 1663 1664 if (dump_reloc_info 1665 && (section->flags & SEC_RELOC) != 0) 1666 { 1667 long relsize; 1668 1669 relsize = bfd_get_reloc_upper_bound (abfd, section); 1670 if (relsize < 0) 1671 bfd_fatal (bfd_get_filename (abfd)); 1672 1673 if (relsize > 0) 1674 { 1675 long relcount; 1676 1677 relbuf = (arelent **) xmalloc (relsize); 1678 relcount = bfd_canonicalize_reloc (abfd, section, relbuf, syms); 1679 if (relcount < 0) 1680 bfd_fatal (bfd_get_filename (abfd)); 1681 1682 /* Sort the relocs by address. */ 1683 qsort (relbuf, relcount, sizeof (arelent *), compare_relocs); 1684 1685 relpp = relbuf; 1686 relppend = relpp + relcount; 1687 1688 /* Skip over the relocs belonging to addresses below the 1689 start address. */ 1690 if (start_address != (bfd_vma) -1) 1691 { 1692 while (relpp < relppend 1693 && (*relpp)->address < start_address) 1694 ++relpp; 1695 } 1696 } 1697 } 1698 1699 printf (_("Disassembly of section %s:\n"), section->name); 1700 1701 datasize = bfd_get_section_size_before_reloc (section); 1702 if (datasize == 0) 1703 continue; 1704 1705 data = (bfd_byte *) xmalloc ((size_t) datasize); 1706 1707 bfd_get_section_contents (abfd, section, data, 0, datasize); 1708 1709 aux.sec = section; 1710 disasm_info.buffer = data; 1711 disasm_info.buffer_vma = section->vma; 1712 disasm_info.buffer_length = datasize; 1713 if (start_address == (bfd_vma) -1 1714 || start_address < disasm_info.buffer_vma) 1715 addr_offset = 0; 1716 else 1717 addr_offset = start_address - disasm_info.buffer_vma; 1718 if (stop_address == (bfd_vma) -1) 1719 stop_offset = datasize / opb; 1720 else 1721 { 1722 if (stop_address < disasm_info.buffer_vma) 1723 stop_offset = 0; 1724 else 1725 stop_offset = stop_address - disasm_info.buffer_vma; 1726 if (stop_offset > disasm_info.buffer_length / opb) 1727 stop_offset = disasm_info.buffer_length / opb; 1728 } 1729 1730 sym = find_symbol_for_address (abfd, section, section->vma + addr_offset, 1731 true, &place); 1732 1733 while (addr_offset < stop_offset) 1734 { 1735 asymbol *nextsym; 1736 unsigned long nextstop_offset; 1737 boolean insns; 1738 1739 if (sym != NULL && bfd_asymbol_value (sym) <= section->vma + addr_offset) 1740 { 1741 int x; 1742 1743 for (x = place; 1744 (x < sorted_symcount 1745 && bfd_asymbol_value (sorted_syms[x]) <= section->vma + addr_offset); 1746 ++x) 1747 continue; 1748 disasm_info.symbols = & sorted_syms[place]; 1749 disasm_info.num_symbols = x - place; 1750 } 1751 else 1752 disasm_info.symbols = NULL; 1753 1754 if (! prefix_addresses) 1755 { 1756 printf ("\n"); 1757 objdump_print_addr_with_sym (abfd, section, sym, 1758 section->vma + addr_offset, 1759 &disasm_info, 1760 false); 1761 printf (":\n"); 1762 } 1763 1764 if (sym != NULL && bfd_asymbol_value (sym) > section->vma + addr_offset) 1765 nextsym = sym; 1766 else if (sym == NULL) 1767 nextsym = NULL; 1768 else 1769 { 1770 /* Search forward for the next appropriate symbol in 1771 SECTION. Note that all the symbols are sorted 1772 together into one big array, and that some sections 1773 may have overlapping addresses. */ 1774 while (place < sorted_symcount 1775 && (sorted_syms[place]->section != section 1776 || (bfd_asymbol_value (sorted_syms[place]) 1777 <= bfd_asymbol_value (sym)))) 1778 ++place; 1779 if (place >= sorted_symcount) 1780 nextsym = NULL; 1781 else 1782 nextsym = sorted_syms[place]; 1783 } 1784 1785 if (sym != NULL && bfd_asymbol_value (sym) > section->vma + addr_offset) 1786 { 1787 nextstop_offset = bfd_asymbol_value (sym) - section->vma; 1788 if (nextstop_offset > stop_offset) 1789 nextstop_offset = stop_offset; 1790 } 1791 else if (nextsym == NULL) 1792 nextstop_offset = stop_offset; 1793 else 1794 { 1795 nextstop_offset = bfd_asymbol_value (nextsym) - section->vma; 1796 if (nextstop_offset > stop_offset) 1797 nextstop_offset = stop_offset; 1798 } 1799 1800 /* If a symbol is explicitly marked as being an object 1801 rather than a function, just dump the bytes without 1802 disassembling them. */ 1803 if (disassemble_all 1804 || sym == NULL 1805 || bfd_asymbol_value (sym) > section->vma + addr_offset 1806 || ((sym->flags & BSF_OBJECT) == 0 1807 && (strstr (bfd_asymbol_name (sym), "gnu_compiled") 1808 == NULL) 1809 && (strstr (bfd_asymbol_name (sym), "gcc2_compiled") 1810 == NULL)) 1811 || (sym->flags & BSF_FUNCTION) != 0) 1812 insns = true; 1813 else 1814 insns = false; 1815 1816 disassemble_bytes (&disasm_info, disassemble_fn, insns, data, 1817 addr_offset, nextstop_offset, &relpp, relppend); 1818 1819 addr_offset = nextstop_offset; 1820 sym = nextsym; 1821 } 1822 1823 free (data); 1824 if (relbuf != NULL) 1825 free (relbuf); 1826 } 1827 free (sorted_syms); 1828} 1829 1830 1831/* Define a table of stab values and print-strings. We wish the initializer 1832 could be a direct-mapped table, but instead we build one the first 1833 time we need it. */ 1834 1835static void dump_section_stabs PARAMS ((bfd *abfd, char *stabsect_name, 1836 char *strsect_name)); 1837 1838/* Dump the stabs sections from an object file that has a section that 1839 uses Sun stabs encoding. */ 1840 1841static void 1842dump_stabs (abfd) 1843 bfd *abfd; 1844{ 1845 dump_section_stabs (abfd, ".stab", ".stabstr"); 1846 dump_section_stabs (abfd, ".stab.excl", ".stab.exclstr"); 1847 dump_section_stabs (abfd, ".stab.index", ".stab.indexstr"); 1848 dump_section_stabs (abfd, "$GDB_SYMBOLS$", "$GDB_STRINGS$"); 1849} 1850 1851static bfd_byte *stabs; 1852static bfd_size_type stab_size; 1853 1854static char *strtab; 1855static bfd_size_type stabstr_size; 1856 1857/* Read ABFD's stabs section STABSECT_NAME into `stabs' 1858 and string table section STRSECT_NAME into `strtab'. 1859 If the section exists and was read, allocate the space and return true. 1860 Otherwise return false. */ 1861 1862static boolean 1863read_section_stabs (abfd, stabsect_name, strsect_name) 1864 bfd *abfd; 1865 const char *stabsect_name; 1866 const char *strsect_name; 1867{ 1868 asection *stabsect, *stabstrsect; 1869 1870 stabsect = bfd_get_section_by_name (abfd, stabsect_name); 1871 if (0 == stabsect) 1872 { 1873 printf (_("No %s section present\n\n"), stabsect_name); 1874 return false; 1875 } 1876 1877 stabstrsect = bfd_get_section_by_name (abfd, strsect_name); 1878 if (0 == stabstrsect) 1879 { 1880 non_fatal (_("%s has no %s section"), 1881 bfd_get_filename (abfd), strsect_name); 1882 exit_status = 1; 1883 return false; 1884 } 1885 1886 stab_size = bfd_section_size (abfd, stabsect); 1887 stabstr_size = bfd_section_size (abfd, stabstrsect); 1888 1889 stabs = (bfd_byte *) xmalloc (stab_size); 1890 strtab = (char *) xmalloc (stabstr_size); 1891 1892 if (! bfd_get_section_contents (abfd, stabsect, (PTR) stabs, 0, stab_size)) 1893 { 1894 non_fatal (_("Reading %s section of %s failed: %s"), 1895 stabsect_name, bfd_get_filename (abfd), 1896 bfd_errmsg (bfd_get_error ())); 1897 free (stabs); 1898 free (strtab); 1899 exit_status = 1; 1900 return false; 1901 } 1902 1903 if (! bfd_get_section_contents (abfd, stabstrsect, (PTR) strtab, 0, 1904 stabstr_size)) 1905 { 1906 non_fatal (_("Reading %s section of %s failed: %s\n"), 1907 strsect_name, bfd_get_filename (abfd), 1908 bfd_errmsg (bfd_get_error ())); 1909 free (stabs); 1910 free (strtab); 1911 exit_status = 1; 1912 return false; 1913 } 1914 1915 return true; 1916} 1917 1918/* Stabs entries use a 12 byte format: 1919 4 byte string table index 1920 1 byte stab type 1921 1 byte stab other field 1922 2 byte stab desc field 1923 4 byte stab value 1924 FIXME: This will have to change for a 64 bit object format. */ 1925 1926#define STRDXOFF (0) 1927#define TYPEOFF (4) 1928#define OTHEROFF (5) 1929#define DESCOFF (6) 1930#define VALOFF (8) 1931#define STABSIZE (12) 1932 1933/* Print ABFD's stabs section STABSECT_NAME (in `stabs'), 1934 using string table section STRSECT_NAME (in `strtab'). */ 1935 1936static void 1937print_section_stabs (abfd, stabsect_name, strsect_name) 1938 bfd *abfd; 1939 const char *stabsect_name; 1940 const char *strsect_name ATTRIBUTE_UNUSED; 1941{ 1942 int i; 1943 unsigned file_string_table_offset = 0, next_file_string_table_offset = 0; 1944 bfd_byte *stabp, *stabs_end; 1945 1946 stabp = stabs; 1947 stabs_end = stabp + stab_size; 1948 1949 printf (_("Contents of %s section:\n\n"), stabsect_name); 1950 printf ("Symnum n_type n_othr n_desc n_value n_strx String\n"); 1951 1952 /* Loop through all symbols and print them. 1953 1954 We start the index at -1 because there is a dummy symbol on 1955 the front of stabs-in-{coff,elf} sections that supplies sizes. */ 1956 1957 for (i = -1; stabp < stabs_end; stabp += STABSIZE, i++) 1958 { 1959 const char *name; 1960 unsigned long strx; 1961 unsigned char type, other; 1962 unsigned short desc; 1963 bfd_vma value; 1964 1965 strx = bfd_h_get_32 (abfd, stabp + STRDXOFF); 1966 type = bfd_h_get_8 (abfd, stabp + TYPEOFF); 1967 other = bfd_h_get_8 (abfd, stabp + OTHEROFF); 1968 desc = bfd_h_get_16 (abfd, stabp + DESCOFF); 1969 value = bfd_h_get_32 (abfd, stabp + VALOFF); 1970 1971 printf ("\n%-6d ", i); 1972 /* Either print the stab name, or, if unnamed, print its number 1973 again (makes consistent formatting for tools like awk). */ 1974 name = bfd_get_stab_name (type); 1975 if (name != NULL) 1976 printf ("%-6s", name); 1977 else if (type == N_UNDF) 1978 printf ("HdrSym"); 1979 else 1980 printf ("%-6d", type); 1981 printf (" %-6d %-6d ", other, desc); 1982 printf_vma (value); 1983 printf (" %-6lu", strx); 1984 1985 /* Symbols with type == 0 (N_UNDF) specify the length of the 1986 string table associated with this file. We use that info 1987 to know how to relocate the *next* file's string table indices. */ 1988 1989 if (type == N_UNDF) 1990 { 1991 file_string_table_offset = next_file_string_table_offset; 1992 next_file_string_table_offset += value; 1993 } 1994 else 1995 { 1996 /* Using the (possibly updated) string table offset, print the 1997 string (if any) associated with this symbol. */ 1998 1999 if ((strx + file_string_table_offset) < stabstr_size) 2000 printf (" %s", &strtab[strx + file_string_table_offset]); 2001 else 2002 printf (" *"); 2003 } 2004 } 2005 printf ("\n\n"); 2006} 2007 2008static void 2009dump_section_stabs (abfd, stabsect_name, strsect_name) 2010 bfd *abfd; 2011 char *stabsect_name; 2012 char *strsect_name; 2013{ 2014 asection *s; 2015 2016 /* Check for section names for which stabsect_name is a prefix, to 2017 handle .stab0, etc. */ 2018 for (s = abfd->sections; 2019 s != NULL; 2020 s = s->next) 2021 { 2022 int len; 2023 2024 len = strlen (stabsect_name); 2025 2026 /* If the prefix matches, and the files section name ends with a 2027 nul or a digit, then we match. I.e., we want either an exact 2028 match or a section followed by a number. */ 2029 if (strncmp (stabsect_name, s->name, len) == 0 2030 && (s->name[len] == '\000' 2031 || isdigit ((unsigned char) s->name[len]))) 2032 { 2033 if (read_section_stabs (abfd, s->name, strsect_name)) 2034 { 2035 print_section_stabs (abfd, s->name, strsect_name); 2036 free (stabs); 2037 free (strtab); 2038 } 2039 } 2040 } 2041} 2042 2043static void 2044dump_bfd_header (abfd) 2045 bfd *abfd; 2046{ 2047 char *comma = ""; 2048 2049 printf (_("architecture: %s, "), 2050 bfd_printable_arch_mach (bfd_get_arch (abfd), 2051 bfd_get_mach (abfd))); 2052 printf (_("flags 0x%08x:\n"), abfd->flags); 2053 2054#define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";} 2055 PF (HAS_RELOC, "HAS_RELOC"); 2056 PF (EXEC_P, "EXEC_P"); 2057 PF (HAS_LINENO, "HAS_LINENO"); 2058 PF (HAS_DEBUG, "HAS_DEBUG"); 2059 PF (HAS_SYMS, "HAS_SYMS"); 2060 PF (HAS_LOCALS, "HAS_LOCALS"); 2061 PF (DYNAMIC, "DYNAMIC"); 2062 PF (WP_TEXT, "WP_TEXT"); 2063 PF (D_PAGED, "D_PAGED"); 2064 PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE"); 2065 printf (_("\nstart address 0x")); 2066 printf_vma (abfd->start_address); 2067 printf ("\n"); 2068} 2069 2070static void 2071dump_bfd_private_header (abfd) 2072bfd *abfd; 2073{ 2074 bfd_print_private_bfd_data (abfd, stdout); 2075} 2076 2077/* Dump selected contents of ABFD */ 2078 2079static void 2080dump_bfd (abfd) 2081 bfd *abfd; 2082{ 2083 /* If we are adjusting section VMA's, change them all now. Changing 2084 the BFD information is a hack. However, we must do it, or 2085 bfd_find_nearest_line will not do the right thing. */ 2086 if (adjust_section_vma != 0) 2087 { 2088 asection *s; 2089 2090 for (s = abfd->sections; s != NULL; s = s->next) 2091 { 2092 s->vma += adjust_section_vma; 2093 s->lma += adjust_section_vma; 2094 } 2095 } 2096 2097 printf (_("\n%s: file format %s\n"), bfd_get_filename (abfd), 2098 abfd->xvec->name); 2099 if (dump_ar_hdrs) 2100 print_arelt_descr (stdout, abfd, true); 2101 if (dump_file_header) 2102 dump_bfd_header (abfd); 2103 if (dump_private_headers) 2104 dump_bfd_private_header (abfd); 2105 putchar ('\n'); 2106 if (dump_section_headers) 2107 dump_headers (abfd); 2108 if (dump_symtab || dump_reloc_info || disassemble || dump_debugging) 2109 { 2110 syms = slurp_symtab (abfd); 2111 } 2112 if (dump_dynamic_symtab || dump_dynamic_reloc_info) 2113 { 2114 dynsyms = slurp_dynamic_symtab (abfd); 2115 } 2116 if (dump_symtab) 2117 dump_symbols (abfd, false); 2118 if (dump_dynamic_symtab) 2119 dump_symbols (abfd, true); 2120 if (dump_stab_section_info) 2121 dump_stabs (abfd); 2122 if (dump_reloc_info && ! disassemble) 2123 dump_relocs (abfd); 2124 if (dump_dynamic_reloc_info) 2125 dump_dynamic_relocs (abfd); 2126 if (dump_section_contents) 2127 dump_data (abfd); 2128 if (disassemble) 2129 disassemble_data (abfd); 2130 if (dump_debugging) 2131 { 2132 PTR dhandle; 2133 2134 dhandle = read_debugging_info (abfd, syms, symcount); 2135 if (dhandle != NULL) 2136 { 2137 if (! print_debugging_info (stdout, dhandle)) 2138 { 2139 non_fatal (_("%s: printing debugging information failed"), 2140 bfd_get_filename (abfd)); 2141 exit_status = 1; 2142 } 2143 } 2144 } 2145 if (syms) 2146 { 2147 free (syms); 2148 syms = NULL; 2149 } 2150 if (dynsyms) 2151 { 2152 free (dynsyms); 2153 dynsyms = NULL; 2154 } 2155} 2156 2157static void 2158display_bfd (abfd) 2159 bfd *abfd; 2160{ 2161 char **matching; 2162 2163 if (bfd_check_format_matches (abfd, bfd_object, &matching)) 2164 { 2165 dump_bfd (abfd); 2166 return; 2167 } 2168 2169 if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 2170 { 2171 nonfatal (bfd_get_filename (abfd)); 2172 list_matching_formats (matching); 2173 free (matching); 2174 return; 2175 } 2176 2177 if (bfd_get_error () != bfd_error_file_not_recognized) 2178 { 2179 nonfatal (bfd_get_filename (abfd)); 2180 return; 2181 } 2182 2183 if (bfd_check_format_matches (abfd, bfd_core, &matching)) 2184 { 2185 dump_bfd (abfd); 2186 return; 2187 } 2188 2189 nonfatal (bfd_get_filename (abfd)); 2190 2191 if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 2192 { 2193 list_matching_formats (matching); 2194 free (matching); 2195 } 2196} 2197 2198static void 2199display_file (filename, target) 2200 char *filename; 2201 char *target; 2202{ 2203 bfd *file, *arfile = (bfd *) NULL; 2204 2205 file = bfd_openr (filename, target); 2206 if (file == NULL) 2207 { 2208 nonfatal (filename); 2209 return; 2210 } 2211 2212 if (bfd_check_format (file, bfd_archive) == true) 2213 { 2214 bfd *last_arfile = NULL; 2215 2216 printf (_("In archive %s:\n"), bfd_get_filename (file)); 2217 for (;;) 2218 { 2219 bfd_set_error (bfd_error_no_error); 2220 2221 arfile = bfd_openr_next_archived_file (file, arfile); 2222 if (arfile == NULL) 2223 { 2224 if (bfd_get_error () != bfd_error_no_more_archived_files) 2225 nonfatal (bfd_get_filename (file)); 2226 break; 2227 } 2228 2229 display_bfd (arfile); 2230 2231 if (last_arfile != NULL) 2232 bfd_close (last_arfile); 2233 last_arfile = arfile; 2234 } 2235 2236 if (last_arfile != NULL) 2237 bfd_close (last_arfile); 2238 } 2239 else 2240 display_bfd (file); 2241 2242 bfd_close (file); 2243} 2244 2245/* Actually display the various requested regions */ 2246 2247static void 2248dump_data (abfd) 2249 bfd *abfd; 2250{ 2251 asection *section; 2252 bfd_byte *data = 0; 2253 bfd_size_type datasize = 0; 2254 bfd_size_type addr_offset; 2255 bfd_size_type start_offset, stop_offset; 2256 unsigned int opb = bfd_octets_per_byte (abfd); 2257 2258 for (section = abfd->sections; section != NULL; section = 2259 section->next) 2260 { 2261 int onaline = 16; 2262 2263 if (only == (char *) NULL || 2264 strcmp (only, section->name) == 0) 2265 { 2266 if (section->flags & SEC_HAS_CONTENTS) 2267 { 2268 printf (_("Contents of section %s:\n"), section->name); 2269 2270 if (bfd_section_size (abfd, section) == 0) 2271 continue; 2272 data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, section)); 2273 datasize = bfd_section_size (abfd, section); 2274 2275 2276 bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_section_size (abfd, section)); 2277 2278 if (start_address == (bfd_vma) -1 2279 || start_address < section->vma) 2280 start_offset = 0; 2281 else 2282 start_offset = start_address - section->vma; 2283 if (stop_address == (bfd_vma) -1) 2284 stop_offset = bfd_section_size (abfd, section) / opb; 2285 else 2286 { 2287 if (stop_address < section->vma) 2288 stop_offset = 0; 2289 else 2290 stop_offset = stop_address - section->vma; 2291 if (stop_offset > bfd_section_size (abfd, section) / opb) 2292 stop_offset = bfd_section_size (abfd, section) / opb; 2293 } 2294 for (addr_offset = start_offset; 2295 addr_offset < stop_offset; addr_offset += onaline) 2296 { 2297 bfd_size_type j; 2298 2299 printf (" %04lx ", (unsigned long int) 2300 (addr_offset + section->vma)); 2301 for (j = addr_offset * opb; 2302 j < addr_offset * opb + onaline; j++) 2303 { 2304 if (j < stop_offset * opb) 2305 printf ("%02x", (unsigned) (data[j])); 2306 else 2307 printf (" "); 2308 if ((j & 3) == 3) 2309 printf (" "); 2310 } 2311 2312 printf (" "); 2313 for (j = addr_offset; j < addr_offset * opb + onaline; j++) 2314 { 2315 if (j >= stop_offset * opb) 2316 printf (" "); 2317 else 2318 printf ("%c", isprint (data[j]) ? data[j] : '.'); 2319 } 2320 putchar ('\n'); 2321 } 2322 free (data); 2323 } 2324 } 2325 } 2326} 2327 2328/* Should perhaps share code and display with nm? */ 2329static void 2330dump_symbols (abfd, dynamic) 2331 bfd *abfd ATTRIBUTE_UNUSED; 2332 boolean dynamic; 2333{ 2334 asymbol **current; 2335 long max; 2336 long count; 2337 2338 if (dynamic) 2339 { 2340 current = dynsyms; 2341 max = dynsymcount; 2342 if (max == 0) 2343 return; 2344 printf ("DYNAMIC SYMBOL TABLE:\n"); 2345 } 2346 else 2347 { 2348 current = syms; 2349 max = symcount; 2350 if (max == 0) 2351 return; 2352 printf ("SYMBOL TABLE:\n"); 2353 } 2354 2355 for (count = 0; count < max; count++) 2356 { 2357 if (*current) 2358 { 2359 bfd *cur_bfd = bfd_asymbol_bfd (*current); 2360 2361 if (cur_bfd != NULL) 2362 { 2363 const char *name; 2364 char *alloc; 2365 2366 name = bfd_asymbol_name (*current); 2367 alloc = NULL; 2368 if (do_demangle && name != NULL && *name != '\0') 2369 { 2370 const char *n; 2371 2372 /* If we want to demangle the name, we demangle it 2373 here, and temporarily clobber it while calling 2374 bfd_print_symbol. FIXME: This is a gross hack. */ 2375 2376 n = name; 2377 if (bfd_get_symbol_leading_char (cur_bfd) == *n) 2378 ++n; 2379 alloc = cplus_demangle (n, DMGL_ANSI | DMGL_PARAMS); 2380 if (alloc != NULL) 2381 (*current)->name = alloc; 2382 else 2383 (*current)->name = n; 2384 } 2385 2386 bfd_print_symbol (cur_bfd, stdout, *current, 2387 bfd_print_symbol_all); 2388 2389 (*current)->name = name; 2390 if (alloc != NULL) 2391 free (alloc); 2392 2393 printf ("\n"); 2394 } 2395 } 2396 current++; 2397 } 2398 printf ("\n"); 2399 printf ("\n"); 2400} 2401 2402static void 2403dump_relocs (abfd) 2404 bfd *abfd; 2405{ 2406 arelent **relpp; 2407 long relcount; 2408 asection *a; 2409 2410 for (a = abfd->sections; a != (asection *) NULL; a = a->next) 2411 { 2412 long relsize; 2413 2414 if (bfd_is_abs_section (a)) 2415 continue; 2416 if (bfd_is_und_section (a)) 2417 continue; 2418 if (bfd_is_com_section (a)) 2419 continue; 2420 2421 if (only) 2422 { 2423 if (strcmp (only, a->name)) 2424 continue; 2425 } 2426 else if ((a->flags & SEC_RELOC) == 0) 2427 continue; 2428 2429 relsize = bfd_get_reloc_upper_bound (abfd, a); 2430 if (relsize < 0) 2431 bfd_fatal (bfd_get_filename (abfd)); 2432 2433 printf ("RELOCATION RECORDS FOR [%s]:", a->name); 2434 2435 if (relsize == 0) 2436 { 2437 printf (" (none)\n\n"); 2438 } 2439 else 2440 { 2441 relpp = (arelent **) xmalloc (relsize); 2442 relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms); 2443 if (relcount < 0) 2444 bfd_fatal (bfd_get_filename (abfd)); 2445 else if (relcount == 0) 2446 { 2447 printf (" (none)\n\n"); 2448 } 2449 else 2450 { 2451 printf ("\n"); 2452 dump_reloc_set (abfd, a, relpp, relcount); 2453 printf ("\n\n"); 2454 } 2455 free (relpp); 2456 } 2457 } 2458} 2459 2460static void 2461dump_dynamic_relocs (abfd) 2462 bfd *abfd; 2463{ 2464 long relsize; 2465 arelent **relpp; 2466 long relcount; 2467 2468 relsize = bfd_get_dynamic_reloc_upper_bound (abfd); 2469 if (relsize < 0) 2470 bfd_fatal (bfd_get_filename (abfd)); 2471 2472 printf ("DYNAMIC RELOCATION RECORDS"); 2473 2474 if (relsize == 0) 2475 { 2476 printf (" (none)\n\n"); 2477 } 2478 else 2479 { 2480 relpp = (arelent **) xmalloc (relsize); 2481 relcount = bfd_canonicalize_dynamic_reloc (abfd, relpp, dynsyms); 2482 if (relcount < 0) 2483 bfd_fatal (bfd_get_filename (abfd)); 2484 else if (relcount == 0) 2485 { 2486 printf (" (none)\n\n"); 2487 } 2488 else 2489 { 2490 printf ("\n"); 2491 dump_reloc_set (abfd, (asection *) NULL, relpp, relcount); 2492 printf ("\n\n"); 2493 } 2494 free (relpp); 2495 } 2496} 2497 2498static void 2499dump_reloc_set (abfd, sec, relpp, relcount) 2500 bfd *abfd; 2501 asection *sec; 2502 arelent **relpp; 2503 long relcount; 2504{ 2505 arelent **p; 2506 char *last_filename, *last_functionname; 2507 unsigned int last_line; 2508 2509 /* Get column headers lined up reasonably. */ 2510 { 2511 static int width; 2512 if (width == 0) 2513 { 2514 char buf[30]; 2515 sprintf_vma (buf, (bfd_vma) -1); 2516 width = strlen (buf) - 7; 2517 } 2518 printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, ""); 2519 } 2520 2521 last_filename = NULL; 2522 last_functionname = NULL; 2523 last_line = 0; 2524 2525 for (p = relpp; relcount && *p != (arelent *) NULL; p++, relcount--) 2526 { 2527 arelent *q = *p; 2528 const char *filename, *functionname; 2529 unsigned int line; 2530 const char *sym_name; 2531 const char *section_name; 2532 2533 if (start_address != (bfd_vma) -1 2534 && q->address < start_address) 2535 continue; 2536 if (stop_address != (bfd_vma) -1 2537 && q->address > stop_address) 2538 continue; 2539 2540 if (with_line_numbers 2541 && sec != NULL 2542 && bfd_find_nearest_line (abfd, sec, syms, q->address, 2543 &filename, &functionname, &line)) 2544 { 2545 if (functionname != NULL 2546 && (last_functionname == NULL 2547 || strcmp (functionname, last_functionname) != 0)) 2548 { 2549 printf ("%s():\n", functionname); 2550 if (last_functionname != NULL) 2551 free (last_functionname); 2552 last_functionname = xstrdup (functionname); 2553 } 2554 if (line > 0 2555 && (line != last_line 2556 || (filename != NULL 2557 && last_filename != NULL 2558 && strcmp (filename, last_filename) != 0))) 2559 { 2560 printf ("%s:%u\n", filename == NULL ? "???" : filename, line); 2561 last_line = line; 2562 if (last_filename != NULL) 2563 free (last_filename); 2564 if (filename == NULL) 2565 last_filename = NULL; 2566 else 2567 last_filename = xstrdup (filename); 2568 } 2569 } 2570 2571 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) 2572 { 2573 sym_name = (*(q->sym_ptr_ptr))->name; 2574 section_name = (*(q->sym_ptr_ptr))->section->name; 2575 } 2576 else 2577 { 2578 sym_name = NULL; 2579 section_name = NULL; 2580 } 2581 if (sym_name) 2582 { 2583 printf_vma (q->address); 2584 if (q->howto->name) 2585 printf (" %-16s ", q->howto->name); 2586 else 2587 printf (" %-16d ", q->howto->type); 2588 objdump_print_symname (abfd, (struct disassemble_info *) NULL, 2589 *q->sym_ptr_ptr); 2590 } 2591 else 2592 { 2593 if (section_name == (CONST char *) NULL) 2594 section_name = "*unknown*"; 2595 printf_vma (q->address); 2596 printf (" %-16s [%s]", 2597 q->howto->name, 2598 section_name); 2599 } 2600 if (q->addend) 2601 { 2602 printf ("+0x"); 2603 printf_vma (q->addend); 2604 } 2605 printf ("\n"); 2606 } 2607} 2608 2609/* The length of the longest architecture name + 1. */ 2610#define LONGEST_ARCH sizeof("powerpc:common") 2611 2612static const char * 2613endian_string (endian) 2614 enum bfd_endian endian; 2615{ 2616 if (endian == BFD_ENDIAN_BIG) 2617 return "big endian"; 2618 else if (endian == BFD_ENDIAN_LITTLE) 2619 return "little endian"; 2620 else 2621 return "endianness unknown"; 2622} 2623 2624/* List the targets that BFD is configured to support, each followed 2625 by its endianness and the architectures it supports. */ 2626 2627static void 2628display_target_list () 2629{ 2630 extern bfd_target *bfd_target_vector[]; 2631 char *dummy_name; 2632 int t; 2633 2634 dummy_name = choose_temp_base (); 2635 for (t = 0; bfd_target_vector[t]; t++) 2636 { 2637 bfd_target *p = bfd_target_vector[t]; 2638 bfd *abfd = bfd_openw (dummy_name, p->name); 2639 int a; 2640 2641 printf ("%s\n (header %s, data %s)\n", p->name, 2642 endian_string (p->header_byteorder), 2643 endian_string (p->byteorder)); 2644 2645 if (abfd == NULL) 2646 { 2647 nonfatal (dummy_name); 2648 continue; 2649 } 2650 2651 if (! bfd_set_format (abfd, bfd_object)) 2652 { 2653 if (bfd_get_error () != bfd_error_invalid_operation) 2654 nonfatal (p->name); 2655 bfd_close_all_done (abfd); 2656 continue; 2657 } 2658 2659 for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++) 2660 if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0)) 2661 printf (" %s\n", 2662 bfd_printable_arch_mach ((enum bfd_architecture) a, 0)); 2663 bfd_close_all_done (abfd); 2664 } 2665 unlink (dummy_name); 2666 free (dummy_name); 2667} 2668 2669/* Print a table showing which architectures are supported for entries 2670 FIRST through LAST-1 of bfd_target_vector (targets across, 2671 architectures down). */ 2672 2673static void 2674display_info_table (first, last) 2675 int first; 2676 int last; 2677{ 2678 extern bfd_target *bfd_target_vector[]; 2679 int t, a; 2680 char *dummy_name; 2681 2682 /* Print heading of target names. */ 2683 printf ("\n%*s", (int) LONGEST_ARCH, " "); 2684 for (t = first; t < last && bfd_target_vector[t]; t++) 2685 printf ("%s ", bfd_target_vector[t]->name); 2686 putchar ('\n'); 2687 2688 dummy_name = choose_temp_base (); 2689 for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++) 2690 if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0) 2691 { 2692 printf ("%*s ", (int) LONGEST_ARCH - 1, 2693 bfd_printable_arch_mach (a, 0)); 2694 for (t = first; t < last && bfd_target_vector[t]; t++) 2695 { 2696 bfd_target *p = bfd_target_vector[t]; 2697 boolean ok = true; 2698 bfd *abfd = bfd_openw (dummy_name, p->name); 2699 2700 if (abfd == NULL) 2701 { 2702 nonfatal (p->name); 2703 ok = false; 2704 } 2705 2706 if (ok) 2707 { 2708 if (! bfd_set_format (abfd, bfd_object)) 2709 { 2710 if (bfd_get_error () != bfd_error_invalid_operation) 2711 nonfatal (p->name); 2712 ok = false; 2713 } 2714 } 2715 2716 if (ok) 2717 { 2718 if (! bfd_set_arch_mach (abfd, a, 0)) 2719 ok = false; 2720 } 2721 2722 if (ok) 2723 printf ("%s ", p->name); 2724 else 2725 { 2726 int l = strlen (p->name); 2727 while (l--) 2728 putchar ('-'); 2729 putchar (' '); 2730 } 2731 if (abfd != NULL) 2732 bfd_close_all_done (abfd); 2733 } 2734 putchar ('\n'); 2735 } 2736 unlink (dummy_name); 2737 free (dummy_name); 2738} 2739 2740/* Print tables of all the target-architecture combinations that 2741 BFD has been configured to support. */ 2742 2743static void 2744display_target_tables () 2745{ 2746 int t, columns; 2747 extern bfd_target *bfd_target_vector[]; 2748 char *colum; 2749 2750 columns = 0; 2751 colum = getenv ("COLUMNS"); 2752 if (colum != NULL) 2753 columns = atoi (colum); 2754 if (columns == 0) 2755 columns = 80; 2756 2757 t = 0; 2758 while (bfd_target_vector[t] != NULL) 2759 { 2760 int oldt = t, wid; 2761 2762 wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1; 2763 ++t; 2764 while (wid < columns && bfd_target_vector[t] != NULL) 2765 { 2766 int newwid; 2767 2768 newwid = wid + strlen (bfd_target_vector[t]->name) + 1; 2769 if (newwid >= columns) 2770 break; 2771 wid = newwid; 2772 ++t; 2773 } 2774 display_info_table (oldt, t); 2775 } 2776} 2777 2778static void 2779display_info () 2780{ 2781 printf (_("BFD header file version %s\n"), BFD_VERSION); 2782 display_target_list (); 2783 display_target_tables (); 2784} 2785 2786int 2787main (argc, argv) 2788 int argc; 2789 char **argv; 2790{ 2791 int c; 2792 char *target = default_target; 2793 boolean seenflag = false; 2794 2795#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 2796 setlocale (LC_MESSAGES, ""); 2797#endif 2798 bindtextdomain (PACKAGE, LOCALEDIR); 2799 textdomain (PACKAGE); 2800 2801 program_name = *argv; 2802 xmalloc_set_program_name (program_name); 2803 2804 START_PROGRESS (program_name, 0); 2805 2806 bfd_init (); 2807 set_default_bfd_target (); 2808 2809 while ((c = getopt_long (argc, argv, "pib:m:M:VCdDlfahHrRtTxsSj:wE:zgG", 2810 long_options, (int *) 0)) 2811 != EOF) 2812 { 2813 switch (c) 2814 { 2815 case 0: 2816 break; /* we've been given a long option */ 2817 case 'm': 2818 machine = optarg; 2819 break; 2820 case 'M': 2821 disassembler_options = optarg; 2822 break; 2823 case 'j': 2824 only = optarg; 2825 break; 2826 case 'l': 2827 with_line_numbers = true; 2828 break; 2829 case 'b': 2830 target = optarg; 2831 break; 2832 case 'C': 2833 do_demangle = true; 2834 break; 2835 case 'w': 2836 wide_output = true; 2837 break; 2838 case OPTION_ADJUST_VMA: 2839 adjust_section_vma = parse_vma (optarg, "--adjust-vma"); 2840 break; 2841 case OPTION_START_ADDRESS: 2842 start_address = parse_vma (optarg, "--start-address"); 2843 break; 2844 case OPTION_STOP_ADDRESS: 2845 stop_address = parse_vma (optarg, "--stop-address"); 2846 break; 2847 case 'E': 2848 if (strcmp (optarg, "B") == 0) 2849 endian = BFD_ENDIAN_BIG; 2850 else if (strcmp (optarg, "L") == 0) 2851 endian = BFD_ENDIAN_LITTLE; 2852 else 2853 { 2854 non_fatal (_("unrecognized -E option")); 2855 usage (stderr, 1); 2856 } 2857 break; 2858 case OPTION_ENDIAN: 2859 if (strncmp (optarg, "big", strlen (optarg)) == 0) 2860 endian = BFD_ENDIAN_BIG; 2861 else if (strncmp (optarg, "little", strlen (optarg)) == 0) 2862 endian = BFD_ENDIAN_LITTLE; 2863 else 2864 { 2865 non_fatal (_("unrecognized --endian type `%s'"), optarg); 2866 usage (stderr, 1); 2867 } 2868 break; 2869 2870 case 'f': 2871 dump_file_header = true; 2872 seenflag = true; 2873 break; 2874 case 'i': 2875 formats_info = true; 2876 seenflag = true; 2877 break; 2878 case 'p': 2879 dump_private_headers = true; 2880 seenflag = true; 2881 break; 2882 case 'x': 2883 dump_private_headers = true; 2884 dump_symtab = true; 2885 dump_reloc_info = true; 2886 dump_file_header = true; 2887 dump_ar_hdrs = true; 2888 dump_section_headers = true; 2889 seenflag = true; 2890 break; 2891 case 't': 2892 dump_symtab = true; 2893 seenflag = true; 2894 break; 2895 case 'T': 2896 dump_dynamic_symtab = true; 2897 seenflag = true; 2898 break; 2899 case 'd': 2900 disassemble = true; 2901 seenflag = true; 2902 break; 2903 case 'z': 2904 disassemble_zeroes = true; 2905 break; 2906 case 'D': 2907 disassemble = true; 2908 disassemble_all = true; 2909 seenflag = true; 2910 break; 2911 case 'S': 2912 disassemble = true; 2913 with_source_code = true; 2914 seenflag = true; 2915 break; 2916 case 'g': 2917 dump_debugging = 1; 2918 seenflag = true; 2919 break; 2920 case 'G': 2921 dump_stab_section_info = true; 2922 seenflag = true; 2923 break; 2924 case 's': 2925 dump_section_contents = true; 2926 seenflag = true; 2927 break; 2928 case 'r': 2929 dump_reloc_info = true; 2930 seenflag = true; 2931 break; 2932 case 'R': 2933 dump_dynamic_reloc_info = true; 2934 seenflag = true; 2935 break; 2936 case 'a': 2937 dump_ar_hdrs = true; 2938 seenflag = true; 2939 break; 2940 case 'h': 2941 dump_section_headers = true; 2942 seenflag = true; 2943 break; 2944 case 'H': 2945 usage (stdout, 0); 2946 seenflag = true; 2947 case 'V': 2948 show_version = true; 2949 seenflag = true; 2950 break; 2951 2952 default: 2953 usage (stderr, 1); 2954 } 2955 } 2956 2957 if (show_version) 2958 print_version ("objdump"); 2959 2960 if (seenflag == false) 2961 usage (stderr, 2); 2962 2963 if (formats_info) 2964 display_info (); 2965 else 2966 { 2967 if (optind == argc) 2968 display_file ("a.out", target); 2969 else 2970 for (; optind < argc;) 2971 display_file (argv[optind++], target); 2972 } 2973 2974 END_PROGRESS (program_name); 2975 2976 return exit_status; 2977} 2978