From 4cb93e3bbe07704a803fa04e562bcd822764d1af Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Mon, 9 Feb 2009 09:14:15 +0000 Subject: [PATCH] 2009-02-09 Tristan Gingold * NEWS: Mention feature match between objdump and readelf for dumping dwarf info. * doc/binutils.texi (objdump): Document -W/--dwarf improvments to objdump. * objdump.c (usage): Update documentation for -W/--dwarf. (enum option_values): Add OPTION_DWARF. (long_options): --dwarf can accept arguments. (dump_dwarf_section): Also check enabled field. (main): Option -W can accept arguments, code moved to dwarf.c and call dwarf_select_sections_all instead. * readelf.c (process_section_headers): Remove do_debug_lines_decoded. (parse_args): Move code to... * dwarf.c (dwarf_select_sections_by_letters, dwarf_select_sections_by_names): : ...here (new functions). (do_debug_lines_decoded): Remove and replaced by ... (FLAG_DEBUG_LINES_RAW, FLAG_DEBUG_LINES_DECODED): ... new macros. (display_debug_lines): Adjust for previous change. (dwarf_select_sections_all): New function. (debug_displays): Add initializer for enabled field. * dwarf.h (do_debug_lines_decoded): Remove. Add prototypes for the new functions. (struct dwarf_section_display): Add enabled field. --- binutils/ChangeLog | 27 +++++ binutils/NEWS | 7 ++ binutils/doc/binutils.texi | 12 ++- binutils/dwarf.c | 197 ++++++++++++++++++++++++++++++++----- binutils/dwarf.h | 8 +- binutils/objdump.c | 38 ++++--- binutils/readelf.c | 130 +----------------------- 7 files changed, 247 insertions(+), 172 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 531eb502c7..c9318c22f7 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,30 @@ +2009-02-09 Tristan Gingold + + * NEWS: Mention feature match between objdump and readelf for dumping + dwarf info. + + * doc/binutils.texi (objdump): Document -W/--dwarf improvments to + objdump. + + * objdump.c (usage): Update documentation for -W/--dwarf. + (enum option_values): Add OPTION_DWARF. + (long_options): --dwarf can accept arguments. + (dump_dwarf_section): Also check enabled field. + (main): Option -W can accept arguments, code moved to + dwarf.c and call dwarf_select_sections_all instead. + * readelf.c (process_section_headers): Remove do_debug_lines_decoded. + (parse_args): Move code to... + * dwarf.c (dwarf_select_sections_by_letters, + dwarf_select_sections_by_names): : ...here (new functions). + (do_debug_lines_decoded): Remove and replaced by ... + (FLAG_DEBUG_LINES_RAW, FLAG_DEBUG_LINES_DECODED): ... new macros. + (display_debug_lines): Adjust for previous change. + (dwarf_select_sections_all): New function. + (debug_displays): Add initializer for enabled field. + * dwarf.h (do_debug_lines_decoded): Remove. + Add prototypes for the new functions. + (struct dwarf_section_display): Add enabled field. + 2009-02-06 Nick Clifton * po/vi.po: Updated Vietnamese translation. diff --git a/binutils/NEWS b/binutils/NEWS index 680792de50..b4d562c337 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,5 +1,12 @@ -*- text -*- +* Option --dwarf/-W of objdump is now as flexible as readelf --debug-dump/-w. + +* --as-needed now links in a dynamic library if it satisfies undefined + symbols in regular objects, or in other dynamic libraries. In the + latter case the library is not linked if it is found in a DT_NEEDED + entry of one of the libraries already linked. + * Added --prefix=PREFIX and --prefix-strip=LEVEL switches to objdump to add absolute paths for -S. diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index d45d6308b2..bd9a04c233 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -1602,7 +1602,8 @@ objdump [@option{-a}|@option{--archive-headers}] [@option{-r}|@option{--reloc}] [@option{-R}|@option{--dynamic-reloc}] [@option{-s}|@option{--full-contents}] - [@option{-W}|@option{--dwarf}] + [@option{-W[lLiaprmfFsoR]}| + @option{--dwarf}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]] [@option{-G}|@option{--stabs}] [@option{-t}|@option{--syms}] [@option{-T}|@option{--dynamic-syms}] @@ -1957,12 +1958,13 @@ in symbolic form. This is the default except when When disassembling instructions, do not print the instruction bytes. This is the default when @option{--prefix-addresses} is used. -@item -W -@itemx --dwarf +@item -W[lLiaprmfFsoR] +@itemx --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges] @cindex DWARF @cindex debug symbols -Displays the contents of the DWARF debug sections in the file, if any -are present. +Displays the contents of the debug sections in the file, if any are +present. If one of the optional letters or words follows the switch +then only data found in those specific sections will be dumped. @item -G @itemx --stabs diff --git a/binutils/dwarf.c b/binutils/dwarf.c index f6a5a53dcf..2eca61eeab 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -44,7 +44,6 @@ int eh_addr_size; int do_debug_info; int do_debug_abbrevs; int do_debug_lines; -int do_debug_lines_decoded; int do_debug_pubnames; int do_debug_aranges; int do_debug_ranges; @@ -55,6 +54,10 @@ int do_debug_str; int do_debug_loc; int do_wide; +/* Values for do_debug_lines. */ +#define FLAG_DEBUG_LINES_RAW 1 +#define FLAG_DEBUG_LINES_DECODED 2 + dwarf_vma (*byte_get) (unsigned char *, int); dwarf_vma @@ -2781,8 +2784,8 @@ display_debug_lines (struct dwarf_section *section, void *file) { unsigned char *data = section->start; unsigned char *end = data + section->size; - int retValRaw = 0; - int retValDecoded = 0; + int retValRaw = 1; + int retValDecoded = 1; if (load_debug_info (file) == 0) { @@ -2791,14 +2794,13 @@ display_debug_lines (struct dwarf_section *section, void *file) return 0; } - if (do_debug_lines) + if (do_debug_lines & FLAG_DEBUG_LINES_RAW) retValRaw = display_debug_lines_raw (section, data, end); - if (do_debug_lines_decoded) + if (do_debug_lines & FLAG_DEBUG_LINES_DECODED) retValDecoded = display_debug_lines_decoded (section, data, end); - if ((do_debug_lines && !retValRaw) - || (do_debug_lines_decoded && !retValDecoded)) + if (!retValRaw || !retValDecoded) return 0; return 1; @@ -4624,38 +4626,185 @@ free_debug_memory (void) } } +void +dwarf_select_sections_by_names (const char *names) +{ + typedef struct + { + const char * option; + int * variable; + int val; + } + debug_dump_long_opts; + + static const debug_dump_long_opts opts_table [] = + { + /* Please keep this table alpha- sorted. */ + { "Ranges", & do_debug_ranges, 1 }, + { "abbrev", & do_debug_abbrevs, 1 }, + { "aranges", & do_debug_aranges, 1 }, + { "frames", & do_debug_frames, 1 }, + { "frames-interp", & do_debug_frames_interp, 1 }, + { "info", & do_debug_info, 1 }, + { "line", & do_debug_lines, FLAG_DEBUG_LINES_RAW }, /* For backwards compatibility. */ + { "rawline", & do_debug_lines, FLAG_DEBUG_LINES_RAW }, + { "decodedline", & do_debug_lines, FLAG_DEBUG_LINES_DECODED }, + { "loc", & do_debug_loc, 1 }, + { "macro", & do_debug_macinfo, 1 }, + { "pubnames", & do_debug_pubnames, 1 }, + /* This entry is for compatability + with earlier versions of readelf. */ + { "ranges", & do_debug_aranges, 1 }, + { "str", & do_debug_str, 1 }, + { NULL, NULL, 0 } + }; + + const char *p; + + p = names; + while (*p) + { + const debug_dump_long_opts * entry; + + for (entry = opts_table; entry->option; entry++) + { + size_t len = strlen (entry->option); + + if (strncmp (p, entry->option, len) == 0 + && (p[len] == ',' || p[len] == '\0')) + { + * entry->variable |= entry->val; + + /* The --debug-dump=frames-interp option also + enables the --debug-dump=frames option. */ + if (do_debug_frames_interp) + do_debug_frames = 1; + + p += len; + break; + } + } + + if (entry->option == NULL) + { + warn (_("Unrecognized debug option '%s'\n"), p); + p = strchr (p, ','); + if (p == NULL) + break; + } + + if (*p == ',') + p++; + } +} + +void +dwarf_select_sections_by_letters (const char *letters) +{ + unsigned int index = 0; + + while (letters[index]) + switch (letters[index++]) + { + case 'i': + do_debug_info = 1; + break; + + case 'a': + do_debug_abbrevs = 1; + break; + + case 'l': + do_debug_lines |= FLAG_DEBUG_LINES_RAW; + break; + + case 'L': + do_debug_lines |= FLAG_DEBUG_LINES_DECODED; + break; + + case 'p': + do_debug_pubnames = 1; + break; + + case 'r': + do_debug_aranges = 1; + break; + + case 'R': + do_debug_ranges = 1; + break; + + case 'F': + do_debug_frames_interp = 1; + case 'f': + do_debug_frames = 1; + break; + + case 'm': + do_debug_macinfo = 1; + break; + + case 's': + do_debug_str = 1; + break; + + case 'o': + do_debug_loc = 1; + break; + + default: + warn (_("Unrecognized debug option '%s'\n"), optarg); + break; + } +} + +void +dwarf_select_sections_all (void) +{ + do_debug_info = 1; + do_debug_abbrevs = 1; + do_debug_lines = FLAG_DEBUG_LINES_RAW; + do_debug_pubnames = 1; + do_debug_aranges = 1; + do_debug_ranges = 1; + do_debug_frames = 1; + do_debug_macinfo = 1; + do_debug_str = 1; + do_debug_loc = 1; +} + struct dwarf_section_display debug_displays[] = { { { ".debug_abbrev", ".zdebug_abbrev", NULL, NULL, 0, 0 }, - display_debug_abbrev, 0, 0 }, + display_debug_abbrev, &do_debug_abbrevs, 0, 0 }, { { ".debug_aranges", ".zdebug_aranges", NULL, NULL, 0, 0 }, - display_debug_aranges, 0, 0 }, + display_debug_aranges, &do_debug_aranges, 0, 0 }, { { ".debug_frame", ".zdebug_frame", NULL, NULL, 0, 0 }, - display_debug_frames, 1, 0 }, + display_debug_frames, &do_debug_frames, 1, 0 }, { { ".debug_info", ".zdebug_info", NULL, NULL, 0, 0 }, - display_debug_info, 1, 0 }, + display_debug_info, &do_debug_info, 1, 0 }, { { ".debug_line", ".zdebug_line", NULL, NULL, 0, 0 }, - display_debug_lines, 0, 0 }, + display_debug_lines, &do_debug_lines, 0, 0 }, { { ".debug_pubnames", ".zdebug_pubnames", NULL, NULL, 0, 0 }, - display_debug_pubnames, 0, 0 }, + display_debug_pubnames, &do_debug_pubnames, 0, 0 }, { { ".eh_frame", "", NULL, NULL, 0, 0 }, - display_debug_frames, 1, 1 }, + display_debug_frames, &do_debug_frames, 1, 1 }, { { ".debug_macinfo", ".zdebug_macinfo", NULL, NULL, 0, 0 }, - display_debug_macinfo, 0, 0 }, + display_debug_macinfo, &do_debug_macinfo, 0, 0 }, { { ".debug_str", ".zdebug_str", NULL, NULL, 0, 0 }, - display_debug_str, 0, 0 }, + display_debug_str, &do_debug_str, 0, 0 }, { { ".debug_loc", ".zdebug_loc", NULL, NULL, 0, 0 }, - display_debug_loc, 0, 0 }, + display_debug_loc, &do_debug_loc, 0, 0 }, { { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0 }, - display_debug_pubnames, 0, 0 }, + display_debug_pubnames, &do_debug_pubnames, 0, 0 }, { { ".debug_ranges", ".zdebug_ranges", NULL, NULL, 0, 0 }, - display_debug_ranges, 0, 0 }, + display_debug_ranges, &do_debug_ranges, 0, 0 }, { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0 }, - display_debug_not_supported, 0, 0 }, + display_debug_not_supported, NULL, 0, 0 }, { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0 }, - display_debug_not_supported, 0, 0 }, - { { ".debug_types", ".zdebug_types", NULL, NULL, 0, 0 }, - display_debug_not_supported, 0, 0 }, + display_debug_not_supported, NULL, 0, 0 }, + { { ".debug_types", ".zdebug_types", NULL, NULL, 0, 0 }, + display_debug_not_supported, NULL, 0, 0 }, { { ".debug_weaknames", ".zdebug_weaknames", NULL, NULL, 0, 0 }, - display_debug_not_supported, 0, 0 } + display_debug_not_supported, NULL, 0, 0 } }; diff --git a/binutils/dwarf.h b/binutils/dwarf.h index 88595ba286..2b4ed55a64 100644 --- a/binutils/dwarf.h +++ b/binutils/dwarf.h @@ -37,7 +37,7 @@ struct dwarf_section * input file, as determined by load_debug_section(). */ const char *uncompressed_name; const char *compressed_name; - const char* name; + const char *name; unsigned char *start; dwarf_vma address; dwarf_size_type size; @@ -49,6 +49,7 @@ struct dwarf_section_display { struct dwarf_section section; int (*display) (struct dwarf_section *, void *); + int *enabled; unsigned int relocate : 1; unsigned int eh_frame : 1; }; @@ -102,7 +103,6 @@ extern int eh_addr_size; extern int do_debug_info; extern int do_debug_abbrevs; extern int do_debug_lines; -extern int do_debug_lines_decoded; extern int do_debug_pubnames; extern int do_debug_aranges; extern int do_debug_ranges; @@ -120,6 +120,10 @@ extern void free_debug_section (enum dwarf_section_display_enum); extern void free_debug_memory (void); +extern void dwarf_select_sections_by_names (const char *names); +extern void dwarf_select_sections_by_letters (const char *letters); +extern void dwarf_select_sections_all (void); + void *cmalloc (size_t, size_t); void *xcmalloc (size_t, size_t); void *xcrealloc (void *, size_t, size_t); diff --git a/binutils/objdump.c b/binutils/objdump.c index faae6edfdd..b05c384717 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -199,7 +199,9 @@ usage (FILE *stream, int status) -g, --debugging Display debug information in object file\n\ -e, --debugging-tags Display debug information using ctags style\n\ -G, --stabs Display (in raw form) any STABS info in the file\n\ - -W, --dwarf Display DWARF info in the file\n\ + -W[lLiaprmfFsoR] or\n\ + --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\ + Display DWARF info in the file\n\ -t, --syms Display the contents of the symbol table(s)\n\ -T, --dynamic-syms Display the contents of the dynamic symbol table\n\ -r, --reloc Display the relocation entries in the file\n\ @@ -254,6 +256,7 @@ enum option_values OPTION_ENDIAN=150, OPTION_START_ADDRESS, OPTION_STOP_ADDRESS, + OPTION_DWARF, OPTION_PREFIX, OPTION_PREFIX_STRIP, OPTION_ADJUST_VMA @@ -293,7 +296,7 @@ static struct option long_options[]= {"source", no_argument, NULL, 'S'}, {"special-syms", no_argument, &dump_special_syms, 1}, {"include", required_argument, NULL, 'I'}, - {"dwarf", no_argument, NULL, 'W'}, + {"dwarf", optional_argument, NULL, OPTION_DWARF}, {"stabs", no_argument, NULL, 'G'}, {"start-address", required_argument, NULL, OPTION_START_ADDRESS}, {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS}, @@ -2210,8 +2213,10 @@ dump_dwarf_section (bfd *abfd, asection *section, match = name; for (i = 0; i < max; i++) - if (strcmp (debug_displays [i].section.uncompressed_name, match) == 0 - || strcmp (debug_displays [i].section.compressed_name, match) == 0) + if ((strcmp (debug_displays [i].section.uncompressed_name, match) == 0 + || strcmp (debug_displays [i].section.compressed_name, match) == 0) + && debug_displays [i].enabled != NULL + && *debug_displays [i].enabled) { if (!debug_displays [i].eh_frame) { @@ -3148,7 +3153,8 @@ main (int argc, char **argv) bfd_init (); set_default_bfd_target (); - while ((c = getopt_long (argc, argv, "pib:m:M:VvCdDlfFaHhrRtTxsSI:j:wE:zgeGW", + while ((c = getopt_long (argc, argv, + "pib:m:M:VvCdDlfFaHhrRtTxsSI:j:wE:zgeGW::", long_options, (int *) 0)) != EOF) { @@ -3311,16 +3317,18 @@ main (int argc, char **argv) case 'W': dump_dwarf_section_info = TRUE; seenflag = TRUE; - do_debug_info = 1; - do_debug_abbrevs = 1; - do_debug_lines = 1; - do_debug_pubnames = 1; - do_debug_aranges = 1; - do_debug_ranges = 1; - do_debug_frames = 1; - do_debug_macinfo = 1; - do_debug_str = 1; - do_debug_loc = 1; + if (optarg) + dwarf_select_sections_by_letters (optarg); + else + dwarf_select_sections_all (); + break; + case OPTION_DWARF: + dump_dwarf_section_info = TRUE; + seenflag = TRUE; + if (optarg) + dwarf_select_sections_by_names (optarg); + else + dwarf_select_sections_all (); break; case 'G': dump_stab_section_info = TRUE; diff --git a/binutils/readelf.c b/binutils/readelf.c index f1c2eb1631..8820d92302 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -3040,63 +3040,8 @@ parse_args (int argc, char **argv) do_debugging = 1; else { - unsigned int index = 0; - do_debugging = 0; - - while (optarg[index]) - switch (optarg[index++]) - { - case 'i': - do_debug_info = 1; - break; - - case 'a': - do_debug_abbrevs = 1; - break; - - case 'l': - do_debug_lines = 1; - break; - - case 'L': - do_debug_lines_decoded = 1; - break; - - case 'p': - do_debug_pubnames = 1; - break; - - case 'r': - do_debug_aranges = 1; - break; - - case 'R': - do_debug_ranges = 1; - break; - - case 'F': - do_debug_frames_interp = 1; - case 'f': - do_debug_frames = 1; - break; - - case 'm': - do_debug_macinfo = 1; - break; - - case 's': - do_debug_str = 1; - break; - - case 'o': - do_debug_loc = 1; - break; - - default: - warn (_("Unrecognized debug option '%s'\n"), optarg); - break; - } + dwarf_select_sections_by_letters (optarg); } break; case OPTION_DEBUG_DUMP: @@ -3105,74 +3050,8 @@ parse_args (int argc, char **argv) do_debugging = 1; else { - typedef struct - { - const char * option; - int * variable; - } - debug_dump_long_opts; - - debug_dump_long_opts opts_table [] = - { - /* Please keep this table alpha- sorted. */ - { "Ranges", & do_debug_ranges }, - { "abbrev", & do_debug_abbrevs }, - { "aranges", & do_debug_aranges }, - { "frames", & do_debug_frames }, - { "frames-interp", & do_debug_frames_interp }, - { "info", & do_debug_info }, - { "line", & do_debug_lines }, /* For backwards compatibility. */ - { "rawline", & do_debug_lines }, - { "decodedline", & do_debug_lines_decoded }, - { "loc", & do_debug_loc }, - { "macro", & do_debug_macinfo }, - { "pubnames", & do_debug_pubnames }, - /* This entry is for compatability - with earlier versions of readelf. */ - { "ranges", & do_debug_aranges }, - { "str", & do_debug_str }, - { NULL, NULL } - }; - - const char *p; - do_debugging = 0; - - p = optarg; - while (*p) - { - debug_dump_long_opts * entry; - - for (entry = opts_table; entry->option; entry++) - { - size_t len = strlen (entry->option); - - if (strneq (p, entry->option, len) - && (p[len] == ',' || p[len] == '\0')) - { - * entry->variable = 1; - - /* The --debug-dump=frames-interp option also - enables the --debug-dump=frames option. */ - if (do_debug_frames_interp) - do_debug_frames = 1; - - p += len; - break; - } - } - - if (entry->option == NULL) - { - warn (_("Unrecognized debug option '%s'\n"), p); - p = strchr (p, ','); - if (p == NULL) - break; - } - - if (*p == ',') - p++; - } + dwarf_select_sections_by_names (optarg); } break; #ifdef SUPPORT_DISASSEMBLY @@ -4286,7 +4165,7 @@ process_section_headers (FILE *file) else if (section->sh_type == SHT_RELA) CHECK_ENTSIZE (section, i, Rela); else if ((do_debugging || do_debug_info || do_debug_abbrevs - || do_debug_lines || do_debug_lines_decoded || do_debug_pubnames + || do_debug_lines || do_debug_pubnames || do_debug_aranges || do_debug_frames || do_debug_macinfo || do_debug_str || do_debug_loc || do_debug_ranges) && (const_strneq (name, ".debug_") @@ -4300,8 +4179,7 @@ process_section_headers (FILE *file) if (do_debugging || (do_debug_info && streq (name, "info")) || (do_debug_abbrevs && streq (name, "abbrev")) - || ((do_debug_lines || do_debug_lines_decoded) - && streq (name, "line")) + || (do_debug_lines && streq (name, "line")) || (do_debug_pubnames && streq (name, "pubnames")) || (do_debug_aranges && streq (name, "aranges")) || (do_debug_ranges && streq (name, "ranges"))