diff --git a/binutils/NEWS b/binutils/NEWS index 461ddab690..a4d7a61ef2 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,5 +1,10 @@ -*- text -*- +* A new command line --keep-section-symbols has been added to objcopy and + strip. This stops the removal of unused section symbols when the file is + copied. Removing these symbols saves space, but sometimes they are needed by + other tools. + * objcopy --weaken, --weaken-symbol and --weaken-symbols now make undefined symbols weak on targets that support weak symbols. @@ -13,6 +18,25 @@ restored by the use of the --enable-follow-debug-links=no configure time option. + The semantics of the =follow-links option have also been slightly changed. + When enabled, the option allows for the loading of symbol tables and string + tables from the separate files which can be used to enhance the information + displayed when dumping other sections, but it does not automatically imply + that information from the separate files should be displayed. + + If other debug section display options are also enabled (eg + --debug-dump=info) then the contents of matching sections in both the main + file and the separate debuginfo file *will* be displayed. This is because in + most cases the debug section will only be present in one of the files. + + If however non-debug section display options are enabled (eg --sections) then + the contents of matching parts of the separate debuginfo file will *not* be + displayed. This is because in most cases the user probably only wanted to + load the symbol information from the separate debuginfo file. In order to + change this behaviour a new command line option --process-links can be used. + This will allow di0pslay options to applied to both the main file and any + separate debuginfo files. + * Nm has a new command line option: --quiet. This suppresses "no symbols" diagnostic. diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index ee898331dd..a9d1dd3e73 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -1210,6 +1210,8 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}] [@option{-g}|@option{--strip-debug}] [@option{--strip-unneeded}] [@option{-K} @var{symbolname}|@option{--keep-symbol=}@var{symbolname}] + [@option{--keep-file-symbols}] + [@option{--keep-section-symbols}] [@option{-N} @var{symbolname}|@option{--strip-symbol=}@var{symbolname}] [@option{--strip-unneeded-symbol=}@var{symbolname}] [@option{-G} @var{symbolname}|@option{--keep-global-symbol=}@var{symbolname}] @@ -1266,7 +1268,6 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}] [@option{--prefix-sections=}@var{string}] [@option{--prefix-alloc-sections=}@var{string}] [@option{--add-gnu-debuglink=}@var{path-to-file}] - [@option{--keep-file-symbols}] [@option{--only-keep-debug}] [@option{--strip-dwo}] [@option{--extract-dwo}] @@ -1967,6 +1968,11 @@ As long as the debug info file has been installed into one of these locations before the debugger is run everything should work correctly. +@item --keep-section-symbils +When stripping a file, perhaps with @option{--strip-debug} or +@option{--strip-unneeded}, retain any symbols specifying section names, +which would otherwise get stripped. + @item --keep-file-symbols When stripping a file, perhaps with @option{--strip-debug} or @option{--strip-unneeded}, retain any symbols specifying source file names, @@ -2202,6 +2208,7 @@ objdump [@option{-a}|@option{--archive-headers}] @option{--dwarf}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links]] [@option{-WK}|@option{--dwarf=follow-links}] [@option{-WN}|@option{--dwarf=no-follow-links}] + [@option{-L}|@option{--process-links}] [@option{--ctf=}@var{section}] [@option{-G}|@option{--stabs}] [@option{-t}|@option{--syms}] @@ -2441,6 +2448,13 @@ for specification with @option{-b} or @option{-m}. @cindex section information Display information only for section @var{name}. +@item -L +@itemx --process-links +Display the contents of non-debug sections found in separate debuginfo +files that are linked to the main file. This option automatically +implies the @option{-WK} option, and only sections requested by other +command line options will be displayed. + @item -l @itemx --line-numbers @cindex source filenames for object files @@ -3321,6 +3335,7 @@ strip [@option{-F} @var{bfdname} |@option{--target=}@var{bfdname}] [@option{-o} @var{file}] [@option{-p}|@option{--preserve-dates}] [@option{-D}|@option{--enable-deterministic-archives}] [@option{-U}|@option{--disable-deterministic-archives}] + [@option{--keep-section-symbols}] [@option{--keep-file-symbols}] [@option{--only-keep-debug}] [@option{-v} |@option{--verbose}] [@option{-V}|@option{--version}] @@ -3516,6 +3531,11 @@ Remove non-global symbols. Remove compiler-generated local symbols. (These usually start with @samp{L} or @samp{.}.) +@item --keep-section-symbols +When stripping a file, perhaps with @option{--strip-debug} or +@option{--strip-unneeded}, retain any symbols specifying section names, +which would otherwise get stripped. + @item --keep-file-symbols When stripping a file, perhaps with @option{--strip-debug} or @option{--strip-unneeded}, retain any symbols specifying source file names, @@ -4771,6 +4791,7 @@ readelf [@option{-a}|@option{--all}] @option{--debug-dump}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links]] [@option{-wK}|@option{--debug-dump=follow-links}] [@option{-wN}|@option{--debug-dump=no-follow-links}] + [@option{-P}|@option{--process-links}] [@option{--dwarf-depth=@var{n}}] [@option{--dwarf-start=@var{n}}] [@option{--ctf=}@var{section}] @@ -5003,6 +5024,13 @@ command to @command{ar}, but without using the BFD library. @xref{ar}. @itemx --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links] @include debug.options.texi +@item -P +@itemx --process-links +Display the contents of non-debug sections found in separate debuginfo +files that are linked to the main file. This option automatically +implies the @option{-wK} option, and only sections requested by other +command line options will be displayed. + @include ctf.options.texi @item --ctf-symbols=@var{section} @item --ctf-strings=@var{section} diff --git a/binutils/dwarf.c b/binutils/dwarf.c index f50b7eeaeb..15f0bd09dc 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -11277,7 +11277,8 @@ load_separate_debug_info (const char * main_filename, /* FIXME: We do not check to see if there are any other separate debug info files that would also match. */ - printf (_("%s: Found separate debug info file: %s\n\n"), main_filename, debug_filename); + if (do_debug_links) + printf (_("\n%s: Found separate debug info file: %s\n"), main_filename, debug_filename); add_separate_debug_file (debug_filename, debug_handle); /* Do not free debug_filename - it might be referenced inside diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 99e6cad72e..d58f910f2f 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -91,6 +91,7 @@ static int copy_byte = -1; static int interleave = 0; /* Initialised to 4 in copy_main(). */ static int copy_width = 1; +static bfd_boolean keep_section_symbols = FALSE ;/* True if section symbols should be retained. */ static bfd_boolean verbose; /* Print file and target names. */ static bfd_boolean preserve_dates; /* Preserve input file timestamp. */ static int deterministic = -1; /* Enable deterministic archives. */ @@ -335,6 +336,7 @@ enum command_line_switch OPTION_KEEP_FILE_SYMBOLS, OPTION_KEEP_SECTION, OPTION_KEEP_SYMBOLS, + OPTION_KEEP_SECTION_SYMBOLS, OPTION_LOCALIZE_HIDDEN, OPTION_LOCALIZE_SYMBOLS, OPTION_LONG_SECTION_NAMES, @@ -387,6 +389,7 @@ static struct option strip_options[] = {"info", no_argument, 0, OPTION_FORMATS_INFO}, {"input-format", required_argument, 0, 'I'}, /* Obsolete */ {"input-target", required_argument, 0, 'I'}, + {"keep-section-symbols", no_argument, 0, OPTION_KEEP_SECTION_SYMBOLS}, {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS}, {"keep-section", required_argument, 0, OPTION_KEEP_SECTION}, {"keep-symbol", required_argument, 0, 'K'}, @@ -463,6 +466,7 @@ static struct option copy_options[] = {"keep-section", required_argument, 0, OPTION_KEEP_SECTION}, {"keep-symbol", required_argument, 0, 'K'}, {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS}, + {"keep-section-symbols", required_argument, 0, OPTION_KEEP_SECTION_SYMBOLS}, {"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN}, {"localize-symbol", required_argument, 0, 'L'}, {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS}, @@ -595,6 +599,7 @@ copy_usage (FILE *stream, int exit_status) --extract-symbol Remove section contents but keep symbols\n\ --keep-section Do not strip section \n\ -K --keep-symbol Do not strip symbol \n\ + --keep-section-symbols Do not strip section symbols\n\ --keep-file-symbols Do not strip file symbol(s)\n\ --localize-hidden Turn all ELF hidden symbols into locals\n\ -L --localize-symbol Force symbol to be marked as a local\n\ @@ -729,6 +734,7 @@ strip_usage (FILE *stream, int exit_status) -N --strip-symbol= Do not copy symbol \n\ --keep-section= Do not strip section \n\ -K --keep-symbol= Do not strip symbol \n\ + --keep-section-symbols Do not strip section symbols\n\ --keep-file-symbols Do not strip file symbol(s)\n\ -w --wildcard Permit wildcard in symbol comparison\n\ -x --discard-all Remove all non-global symbols\n\ @@ -3196,7 +3202,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch) if ((obfd->flags & (EXEC_P | DYNAMIC)) != 0 && (obfd->flags & HAS_RELOC) == 0) { - if (bfd_keep_unused_section_symbols (obfd)) + if (bfd_keep_unused_section_symbols (obfd) || keep_section_symbols) { /* Non-relocatable inputs may not have the unused section symbols. Mark all section symbols as used to generate @@ -4768,6 +4774,9 @@ strip_main (int argc, char *argv[]) case OPTION_KEEP_FILE_SYMBOLS: keep_file_symbols = 1; break; + case OPTION_KEEP_SECTION_SYMBOLS: + keep_section_symbols = TRUE; + break; case 0: /* We've been given a long option. */ break; @@ -5653,6 +5662,10 @@ copy_main (int argc, char *argv[]) &keep_specific_buffer); break; + case OPTION_KEEP_SECTION_SYMBOLS: + keep_section_symbols = TRUE; + break; + case OPTION_LOCALIZE_HIDDEN: localize_hidden = TRUE; break; diff --git a/binutils/objdump.c b/binutils/objdump.c index 47b23099ec..0aa037384c 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -128,6 +128,7 @@ static const char * source_comment; /* --source_comment. */ static bfd_boolean visualize_jumps = FALSE; /* --visualize-jumps. */ static bfd_boolean color_output = FALSE; /* --visualize-jumps=color. */ static bfd_boolean extended_color_output = FALSE; /* --visualize-jumps=extended-color. */ +static bfd_boolean process_links = FALSE; /* --process-links. */ static int demangle_flags = DMGL_ANSI | DMGL_PARAMS; @@ -247,6 +248,9 @@ usage (FILE *stream, int status) -WN,--dwarf=no-follow-links Do not follow links to separate debug info files (default)\n\ ")); #endif + fprintf (stream, _("\ + -L, --process-links Display the contents of non-debug sections in separate debuginfo files.\n\ +")); #ifdef ENABLE_LIBCTF fprintf (stream, _("\ --ctf=SECTION Display CTF info from SECTION\n\ @@ -383,6 +387,7 @@ static struct option long_options[]= {"line-numbers", no_argument, NULL, 'l'}, {"no-show-raw-insn", no_argument, &show_raw_insn, -1}, {"no-addresses", no_argument, &no_addresses, 1}, + {"process-links", no_argument, &process_links, TRUE}, {"prefix-addresses", no_argument, &prefix_addresses, 1}, {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT}, {"recursion-limit", no_argument, NULL, OPTION_RECURSE_LIMIT}, @@ -4843,6 +4848,9 @@ dump_bfd (bfd *abfd, bfd_boolean is_mainfile) bfd_map_over_sections (abfd, adjust_addresses, &has_reloc); } + if (! is_mainfile && ! process_links) + return; + if (! dump_debugging_tags && ! suppress_bfd_header) printf (_("\n%s: file format %s\n"), sanitize_string (bfd_get_filename (abfd)), @@ -5357,6 +5365,10 @@ main (int argc, char **argv) do_demangle = TRUE; seenflag = TRUE; break; + case 'L': + process_links = TRUE; + do_follow_links = TRUE; + break; case 'W': dump_dwarf_section_info = TRUE; seenflag = TRUE; diff --git a/binutils/readelf.c b/binutils/readelf.c index 7c8496c17a..c862839b4c 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -238,6 +238,7 @@ static bfd_boolean is_32bit_elf = FALSE; static bfd_boolean decompress_dumps = FALSE; static bfd_boolean do_not_show_symbol_truncation = FALSE; static bfd_boolean do_demangle = FALSE; /* Pretty print C++ symbol names. */ +static bfd_boolean process_links = FALSE; static int demangle_flags = DMGL_ANSI | DMGL_PARAMS; static char *dump_ctf_parent_name; @@ -259,6 +260,7 @@ struct group typedef struct filedata { const char * file_name; + bfd_boolean is_separate; FILE * handle; bfd_size_type file_size; Elf_Internal_Ehdr file_header; @@ -675,7 +677,7 @@ print_symbol (signed int width, const char * symbol) static const char * printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec) { -#define MAX_PRINT_SEC_NAME_LEN 128 +#define MAX_PRINT_SEC_NAME_LEN 256 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1]; const char * name = SECTION_NAME_PRINT (sec); char * buf = sec_name_buf; @@ -4546,6 +4548,7 @@ static struct option options[] = {"segments", no_argument, 0, 'l'}, {"full-section-name",no_argument, 0, 'N'}, {"notes", no_argument, 0, 'n'}, + {"process-links", no_argument, 0, 'P'}, {"string-dump", required_argument, 0, 'p'}, {"relocated-dump", required_argument, 0, 'R'}, {"relocs", no_argument, 0, 'r'}, @@ -4624,12 +4627,14 @@ usage (FILE * stream) -R --relocated-dump=\n\ Dump the contents of section as relocated bytes\n\ -z --decompress Decompress section before dumping it\n\ - -w[lLiaprmfFsoORtUuTgAck] or\n\ + -w[lLiaprmfFsoORtUuTgAc] or\n\ --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\ =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\ =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\ - =addr,=cu_index,=links]\n\ - Display the contents of DWARF debug sections\n")); + =addr,=cu_index]\n\ + Display the contents of DWARF debug sections\n\ + -wk,--debug-dump=links Display the contents of sections that link to separate debuginfo files\n\ + -P,--process-links Display the contents of non-debug sections in separate debuginfo files. (Implies -wK)\n")); #if DEFAULT_FOR_FOLLOW_LINKS fprintf (stream, _("\ -wK,--debug-dump=follow-links Follow links to separate debug info files (default)\n\ @@ -4759,7 +4764,7 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv) usage (stderr); while ((c = getopt_long - (argc, argv, "ACDHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF) + (argc, argv, "ACDHILNPR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF) { switch (c) { @@ -4837,6 +4842,10 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv) case 'L': do_checks = TRUE; break; + case 'P': + process_links = TRUE; + do_follow_links = TRUE; + break; case 'x': request_dump (dumpdata, HEX_DUMP); break; @@ -5032,13 +5041,17 @@ process_file_header (Filedata * filedata) return FALSE; } - init_dwarf_regnames_by_elf_machine_code (header->e_machine); + if (! filedata->is_separate) + init_dwarf_regnames_by_elf_machine_code (header->e_machine); if (do_header) { unsigned i; - printf (_("ELF Header:\n")); + if (filedata->is_separate) + printf (_("ELF Header in linked file '%s':\n"), filedata->file_name); + else + printf (_("ELF Header:\n")); printf (_(" Magic: ")); for (i = 0; i < EI_NIDENT; i++) printf ("%2.2x ", header->e_ident[i]); @@ -5294,13 +5307,24 @@ process_program_headers (Filedata * filedata) return FALSE; } else if (do_segments) - printf (_("\nThere are no program headers in this file.\n")); + { + if (filedata->is_separate) + printf (_("\nThere are no program headers in linked file '%s'.\n"), + filedata->file_name); + else + printf (_("\nThere are no program headers in this file.\n")); + } return TRUE; } if (do_segments && !do_header) { - printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type)); + if (filedata->is_separate) + printf ("\nIn linked file '%s' the ELF file type is %s\n", + filedata->file_name, + get_file_type (filedata->file_header.e_type)); + else + printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type)); printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry)); printf (ngettext ("There is %d program header, starting at offset %s\n", "There are %d program headers, starting at offset %s\n", @@ -6362,13 +6386,18 @@ process_section_headers (Filedata * filedata) } if (do_sections && !do_header) - printf (ngettext ("There is %d section header, " - "starting at offset 0x%lx:\n", - "There are %d section headers, " - "starting at offset 0x%lx:\n", - filedata->file_header.e_shnum), - filedata->file_header.e_shnum, - (unsigned long) filedata->file_header.e_shoff); + { + if (filedata->is_separate && process_links) + printf (_("In linked file '%s': "), filedata->file_name); + if (! filedata->is_separate || process_links) + printf (ngettext ("There is %d section header, " + "starting at offset 0x%lx:\n", + "There are %d section headers, " + "starting at offset 0x%lx:\n", + filedata->file_header.e_shnum), + filedata->file_header.e_shnum, + (unsigned long) filedata->file_header.e_shoff); + } if (is_32bit_elf) { @@ -6626,7 +6655,12 @@ process_section_headers (Filedata * filedata) if (! do_sections) return TRUE; - if (filedata->file_header.e_shnum > 1) + if (filedata->is_separate && ! process_links) + return TRUE; + + if (filedata->is_separate) + printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name); + else if (filedata->file_header.e_shnum > 1) printf (_("\nSection Headers:\n")); else printf (_("\nSection Header:\n")); @@ -7112,8 +7146,13 @@ process_section_groups (Filedata * filedata) if (filedata->file_header.e_shnum == 0) { if (do_section_groups) - printf (_("\nThere are no sections to group in this file.\n")); - + { + if (filedata->is_separate) + printf (_("\nThere are no sections group in linked file '%s'.\n"), + filedata->file_name); + else + printf (_("\nThere are no section groups in this file.\n")); + } return TRUE; } @@ -7146,7 +7185,13 @@ process_section_groups (Filedata * filedata) if (filedata->group_count == 0) { if (do_section_groups) - printf (_("\nThere are no section groups in this file.\n")); + { + if (filedata->is_separate) + printf (_("\nThere are no section groups in linked file '%s'.\n"), + filedata->file_name); + else + printf (_("\nThere are no section groups in this file.\n")); + } return TRUE; } @@ -7167,6 +7212,10 @@ process_section_groups (Filedata * filedata) num_syms = 0; strtab = NULL; strtab_size = 0; + + if (filedata->is_separate) + printf (_("Section groups in linked file '%s'\n"), filedata->file_name); + for (i = 0, section = filedata->section_headers, group = filedata->section_groups; i < filedata->file_header.e_shnum; i++, section++) @@ -7609,9 +7658,15 @@ process_relocs (Filedata * filedata) if (rel_size) { - printf - (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"), - name, rel_offset, rel_size); + if (filedata->is_separate) + printf + (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"), + filedata->file_name, name, rel_offset, rel_size); + else + printf + (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"), + name, rel_offset, rel_size); + dump_relocations (filedata, offset_from_vma (filedata, rel_offset, rel_size), @@ -7629,7 +7684,13 @@ process_relocs (Filedata * filedata) has_dynamic_reloc = TRUE; if (! has_dynamic_reloc) - printf (_("\nThere are no dynamic relocations in this file.\n")); + { + if (filedata->is_separate) + printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"), + filedata->file_name); + else + printf (_("\nThere are no dynamic relocations in this file.\n")); + } } else { @@ -7653,7 +7714,11 @@ process_relocs (Filedata * filedata) int is_rela; unsigned long num_rela; - printf (_("\nRelocation section ")); + if (filedata->is_separate) + printf (_("\nIn linked file '%s' relocation section "), + filedata->file_name); + else + printf (_("\nRelocation section ")); if (filedata->string_table == NULL) printf ("%d", section->sh_name); @@ -7709,14 +7774,24 @@ process_relocs (Filedata * filedata) { if (filedata->dynamic_info[dynamic_relocations [i].size]) { - printf (_("\nThere are no static relocations in this file.")); + if (filedata->is_separate) + printf (_("\nThere are no static relocations in linked file '%s'."), + filedata->file_name); + else + printf (_("\nThere are no static relocations in this file.")); printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n")); break; } } if (i == ARRAY_SIZE (dynamic_relocations)) - printf (_("\nThere are no relocations in this file.\n")); + { + if (filedata->is_separate) + printf (_("\nThere are no relocations in linked file '%s'.\n"), + filedata->file_name); + else + printf (_("\nThere are no relocations in this file.\n")); + } } } @@ -10429,7 +10504,13 @@ process_dynamic_section (Filedata * filedata) if (filedata->dynamic_size == 0) { if (do_dynamic) - printf (_("\nThere is no dynamic section in this file.\n")); + { + if (filedata->is_separate) + printf (_("\nThere is no dynamic section in linked file '%s'.\n"), + filedata->file_name); + else + printf (_("\nThere is no dynamic section in this file.\n")); + } return TRUE; } @@ -10654,12 +10735,30 @@ the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n")); } if (do_dynamic && filedata->dynamic_addr) - printf (ngettext ("\nDynamic section at offset 0x%lx " - "contains %lu entry:\n", - "\nDynamic section at offset 0x%lx " - "contains %lu entries:\n", - filedata->dynamic_nent), - filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent); + { + if (filedata->dynamic_nent == 1) + { + if (filedata->is_separate) + printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains 1 entry:\n"), + filedata->file_name, + filedata->dynamic_addr); + else + printf (_("\nDynamic section at offset 0x%lx contains 1 entry:\n"), + filedata->dynamic_addr); + } + else + { + if (filedata->is_separate) + printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n"), + filedata->file_name, + filedata->dynamic_addr, + (unsigned long) filedata->dynamic_nent); + else + printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"), + filedata->dynamic_addr, + (unsigned long) filedata->dynamic_nent); + } + } if (do_dynamic) printf (_(" Tag Type Name/Value\n")); @@ -11240,14 +11339,22 @@ process_version_sections (Filedata * filedata) found = TRUE; - printf (ngettext ("\nVersion definition section '%s' " - "contains %u entry:\n", - "\nVersion definition section '%s' " - "contains %u entries:\n", - section->sh_info), - printable_section_name (filedata, section), - section->sh_info); - + if (filedata->is_separate) + printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n", + "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n", + section->sh_info), + filedata->file_name, + printable_section_name (filedata, section), + section->sh_info); + else + printf (ngettext ("\nVersion definition section '%s' " + "contains %u entry:\n", + "\nVersion definition section '%s' " + "contains %u entries:\n", + section->sh_info), + printable_section_name (filedata, section), + section->sh_info); + printf (_(" Addr: 0x")); printf_vma (section->sh_addr); printf (_(" Offset: %#08lx Link: %u (%s)\n"), @@ -11379,13 +11486,22 @@ process_version_sections (Filedata * filedata) found = TRUE; - printf (ngettext ("\nVersion needs section '%s' " - "contains %u entry:\n", - "\nVersion needs section '%s' " - "contains %u entries:\n", - section->sh_info), - printable_section_name (filedata, section), section->sh_info); - + if (filedata->is_separate) + printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n", + "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n", + section->sh_info), + filedata->file_name, + printable_section_name (filedata, section), + section->sh_info); + else + printf (ngettext ("\nVersion needs section '%s' " + "contains %u entry:\n", + "\nVersion needs section '%s' " + "contains %u entries:\n", + section->sh_info), + printable_section_name (filedata, section), + section->sh_info); + printf (_(" Addr: 0x")); printf_vma (section->sh_addr); printf (_(" Offset: %#08lx Link: %u (%s)\n"), @@ -11536,12 +11652,21 @@ process_version_sections (Filedata * filedata) break; } - printf (ngettext ("\nVersion symbols section '%s' " - "contains %lu entry:\n", - "\nVersion symbols section '%s' " - "contains %lu entries:\n", - total), - printable_section_name (filedata, section), (unsigned long) total); + if (filedata->is_separate) + printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n", + "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n", + total), + filedata->file_name, + printable_section_name (filedata, section), + (unsigned long) total); + else + printf (ngettext ("\nVersion symbols section '%s' " + "contains %lu entry:\n", + "\nVersion symbols section '%s' " + "contains %lu entries:\n", + total), + printable_section_name (filedata, section), + (unsigned long) total); printf (_(" Addr: 0x")); printf_vma (section->sh_addr); @@ -11744,7 +11869,13 @@ process_version_sections (Filedata * filedata) } if (! found) - printf (_("\nNo version information found in this file.\n")); + { + if (filedata->is_separate) + printf (_("\nNo version information found in linked file '%s'.\n"), + filedata->file_name); + else + printf (_("\nNo version information found in this file.\n")); + } return TRUE; } @@ -12390,8 +12521,14 @@ display_lto_symtab (Filedata * filedata, { if (section->sh_size == 0) { - printf (_("\nLTO Symbol table '%s' is empty!\n"), - printable_section_name (filedata, section)); + if (filedata->is_separate) + printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"), + printable_section_name (filedata, section), + filedata->file_name); + else + printf (_("\nLTO Symbol table '%s' is empty!\n"), + printable_section_name (filedata, section)); + return TRUE; } @@ -12440,25 +12577,29 @@ display_lto_symtab (Filedata * filedata, const unsigned char * data = (const unsigned char *) alloced_data; const unsigned char * end = data + section->sh_size; + if (filedata->is_separate) + printf (_("\nIn linked file '%s': "), filedata->file_name); + else + printf ("\n"); + if (ext_data_orig != NULL) { if (do_wide) - printf (_("\nLTO Symbol table '%s' and extension table '%s' contain:\n"), + printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"), printable_section_name (filedata, section), printable_section_name (filedata, ext)); else { - printf (_("\nLTO Symbol table '%s'\n"), + printf (_("LTO Symbol table '%s'\n"), printable_section_name (filedata, section)); printf (_(" and extension table '%s' contain:\n"), printable_section_name (filedata, ext)); } } else - printf (_("\nLTO Symbol table '%s' contains:\n"), + printf (_("LTO Symbol table '%s' contains:\n"), printable_section_name (filedata, section)); - /* FIXME: Add a wide version. */ if (ext_data_orig != NULL) printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n")); @@ -12590,10 +12731,21 @@ process_symbol_table (Filedata * filedata) { unsigned long si; - printf (ngettext ("\nSymbol table for image contains %lu entry:\n", - "\nSymbol table for image contains %lu entries:\n", - filedata->num_dynamic_syms), - filedata->num_dynamic_syms); + if (filedata->is_separate) + { + printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n", + "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n", + filedata->num_dynamic_syms), + filedata->file_name, + filedata->num_dynamic_syms); + } + else + { + printf (ngettext ("\nSymbol table for image contains %lu entry:\n", + "\nSymbol table for image contains %lu entries:\n", + filedata->num_dynamic_syms), + filedata->num_dynamic_syms); + } if (is_32bit_elf) printf (_(" Num: Value Size Type Bind Vis Ndx Name\n")); else @@ -12632,11 +12784,20 @@ process_symbol_table (Filedata * filedata) } num_syms = section->sh_size / section->sh_entsize; - printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n", - "\nSymbol table '%s' contains %lu entries:\n", - num_syms), - printable_section_name (filedata, section), - num_syms); + + if (filedata->is_separate) + printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n", + "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n", + num_syms), + filedata->file_name, + printable_section_name (filedata, section), + num_syms); + else + printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n", + "\nSymbol table '%s' contains %lu entries:\n", + num_syms), + printable_section_name (filedata, section), + num_syms); if (is_32bit_elf) printf (_(" Num: Value Size Type Bind Vis Ndx Name\n")); @@ -12858,7 +13019,7 @@ process_symbol_table (Filedata * filedata) } static bfd_boolean -process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED) +process_syminfo (Filedata * filedata) { unsigned int i; @@ -12871,13 +13032,21 @@ process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED) if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL) return FALSE; - if (filedata->dynamic_addr) + if (filedata->is_separate) + printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n", + "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n", + filedata->dynamic_syminfo_nent), + filedata->file_name, + filedata->dynamic_syminfo_offset, + filedata->dynamic_syminfo_nent); + else printf (ngettext ("\nDynamic info segment at offset 0x%lx " "contains %d entry:\n", "\nDynamic info segment at offset 0x%lx " "contains %d entries:\n", filedata->dynamic_syminfo_nent), - filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent); + filedata->dynamic_syminfo_offset, + filedata->dynamic_syminfo_nent); printf (_(" Num: Name BoundTo Flags\n")); for (i = 0; i < filedata->dynamic_syminfo_nent; ++i) @@ -15003,7 +15172,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, unsigned char * get_build_id (void * data) { - Filedata * filedata = (Filedata *)data; + Filedata * filedata = (Filedata *) data; Elf_Internal_Shdr * shdr; unsigned long i; @@ -15311,8 +15480,14 @@ initialise_dumps_byname (Filedata * filedata) } if (!any) - warn (_("Section '%s' was not dumped because it does not exist!\n"), - cur->name); + { + if (filedata->is_separate) + warn (_("Section '%s' in linked file '%s' was not dumped because it does not exist\n"), + cur->name, filedata->file_name); + else + warn (_("Section '%s' was not dumped because it does not exist\n"), + cur->name); + } } } @@ -15380,7 +15555,11 @@ process_section_contents (Filedata * filedata) { if (filedata->dump.dump_sects[i]) { - warn (_("Section %d was not dumped because it does not exist!\n"), i); + if (filedata->is_separate) + warn (_("Section %d in linked file '%s' was not dumped because it does not exist!\n"), + i, filedata->file_name); + else + warn (_("Section %d was not dumped because it does not exist!\n"), i); res = FALSE; } i++; @@ -20357,10 +20536,14 @@ process_notes_at (Filedata * filedata, external = pnotes; + if (filedata->is_separate) + printf (_("In linked file '%s': "), filedata->file_name); + else + printf ("\n"); if (section) - printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section)); + printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section)); else - printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"), + printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"), (unsigned long) offset, (unsigned long) length); /* NB: Some note sections may have alignment value of 0 or 1. gABI @@ -20658,7 +20841,12 @@ process_notes (Filedata * filedata) if (filedata->file_header.e_phnum > 0) return process_corefile_note_segments (filedata); - printf (_("No note segments present in the core file.\n")); + if (filedata->is_separate) + printf (_("No notes found in linked file '%s'.\n"), + filedata->file_name); + else + printf (_("No notes found file.\n")); + return TRUE; } @@ -20868,7 +21056,7 @@ close_debug_file (void * data) } static Filedata * -open_file (const char * pathname) +open_file (const char * pathname, bfd_boolean is_separate) { struct stat statbuf; Filedata * filedata = NULL; @@ -20887,6 +21075,7 @@ open_file (const char * pathname) filedata->file_size = (bfd_size_type) statbuf.st_size; filedata->file_name = pathname; + filedata->is_separate = is_separate; if (! get_file_header (filedata)) goto fail; @@ -20920,7 +21109,7 @@ open_file (const char * pathname) void * open_debug_file (const char * pathname) { - return open_file (pathname); + return open_file (pathname, TRUE); } /* Process one ELF object file according to the command line options. @@ -21025,10 +21214,35 @@ process_object (Filedata * filedata) for (d = first_separate_info; d != NULL; d = d->next) { - if (! process_section_headers (d->handle)) + if (process_links && ! process_file_header (d->handle)) res = FALSE; - else if (! process_section_contents (d->handle)) + else if (! process_section_headers (d->handle)) res = FALSE; + else if (process_links) + { + if (! process_section_contents (d->handle)) + res = FALSE; + if (! process_section_groups (d->handle)) + res = FALSE; + if (! process_program_headers (d->handle)) + res = FALSE; + if (! process_dynamic_section (d->handle)) + res = FALSE; + if (! process_relocs (d->handle)) + res = FALSE; + if (! process_unwind (d->handle)) + res = FALSE; + if (! process_symbol_table (d->handle)) + res = FALSE; + if (! process_lto_symbol_tables (d->handle)) + res = FALSE; + if (! process_syminfo (d->handle)) + res = FALSE; + if (! process_version_sections (d->handle)) + res = FALSE; + if (! process_notes (d->handle)) + res = FALSE; + } } /* The file handles are closed by the call to free_debug_memory() below. */ @@ -21311,7 +21525,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive) break; } - member_filedata = open_file (member_file_name); + member_filedata = open_file (member_file_name, FALSE); if (member_filedata == NULL) { error (_("Input file '%s' is not readable.\n"), member_file_name); @@ -21444,6 +21658,7 @@ process_file (char * file_name) } filedata->file_size = (bfd_size_type) statbuf.st_size; + filedata->is_separate = FALSE; if (memcmp (armag, ARMAG, SARMAG) == 0) { diff --git a/binutils/testsuite/binutils-all/compress.exp b/binutils/testsuite/binutils-all/compress.exp index 88fef26990..1756f6235c 100644 --- a/binutils/testsuite/binutils-all/compress.exp +++ b/binutils/testsuite/binutils-all/compress.exp @@ -693,7 +693,7 @@ proc test_gnu_debuglink {} { unsupported "$test (build)" return } - set got [remote_exec host "$OBJDUMP -S tmpdir/testprog" "" "/dev/null" "tmpdir/testprog.dump"] + set got [remote_exec host "$OBJDUMP -d tmpdir/testprog" "" "/dev/null" "tmpdir/testprog.dump"] if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { fail "$test (objcopy dump)" return @@ -714,7 +714,7 @@ proc test_gnu_debuglink {} { fail "$test (objcopy link decompress)" return } - set got [remote_exec host "$OBJDUMP -S -WN tmpdir/testprog" "" "/dev/null" "tmpdir/testprog.decompress.dump"] + set got [remote_exec host "$OBJDUMP -d -WK tmpdir/testprog" "" "/dev/null" "tmpdir/testprog.decompress.dump"] if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { fail "$test (objcopy dump decompress)" return @@ -723,7 +723,7 @@ proc test_gnu_debuglink {} { fail "$test (objcopy link compress)" return } - set got [remote_exec host "$OBJDUMP -S -WN tmpdir/testprog" "" "/dev/null" "tmpdir/testprog.compress.dump"] + set got [remote_exec host "$OBJDUMP -d -WK tmpdir/testprog" "" "/dev/null" "tmpdir/testprog.compress.dump"] if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { fail "$test (objcopy dump compress)" return @@ -731,9 +731,9 @@ proc test_gnu_debuglink {} { set src1 tmpdir/testprog.dump set src2 tmpdir/testprog.compress.dump - send_log "cmp ${src1} ${src2}\n" - verbose "cmp ${src1} ${src2}" - set status [remote_exec build cmp "${src1} ${src2}"] + send_log "diff ${src1} ${src2}\n" + verbose "diff ${src1} ${src2}" + set status [remote_exec build diff "${src1} ${src2}"] set exec_output [lindex $status 1] set exec_output [prune_warnings $exec_output] if ![string match "" $exec_output] then { @@ -746,9 +746,9 @@ proc test_gnu_debuglink {} { set src1 tmpdir/testprog.decompress.dump set src2 tmpdir/testprog.compress.dump - send_log "cmp ${src1} ${src2}\n" - verbose "cmp ${src1} ${src2}" - set status [remote_exec build cmp "${src1} ${src2}"] + send_log "diff ${src1} ${src2}\n" + verbose "diff ${src1} ${src2}" + set status [remote_exec build diff "${src1} ${src2}"] set exec_output [lindex $status 1] set exec_output [prune_warnings $exec_output] if ![string match "" $exec_output] then { diff --git a/binutils/testsuite/binutils-all/objdump.WK2 b/binutils/testsuite/binutils-all/objdump.WK2 index 539a0875cf..be7817f240 100644 --- a/binutils/testsuite/binutils-all/objdump.WK2 +++ b/binutils/testsuite/binutils-all/objdump.WK2 @@ -1,5 +1,5 @@ #... -.*debuglink.o: Found separate debug info file:.*linkdebug.debug +.*linkdebug.debug:.* #... Contents of the .debug_str section \(loaded from .*linkdebug.debug\): diff --git a/binutils/testsuite/binutils-all/objdump.WK3 b/binutils/testsuite/binutils-all/objdump.WK3 index 399cf5264e..26ce3f8c8b 100644 --- a/binutils/testsuite/binutils-all/objdump.WK3 +++ b/binutils/testsuite/binutils-all/objdump.WK3 @@ -1,6 +1,4 @@ #... -.*debuglink.o: Found separate debug info file:.*linkdebug.debug -#... .*linkdebug.debug:.* #... .* .debug_abbrev .* diff --git a/binutils/testsuite/binutils-all/objdump.exp b/binutils/testsuite/binutils-all/objdump.exp index 9a0720f95a..c9a7eec75e 100644 --- a/binutils/testsuite/binutils-all/objdump.exp +++ b/binutils/testsuite/binutils-all/objdump.exp @@ -671,8 +671,8 @@ proc test_follow_debuglink { options dumpfile } { } if {[is_elf_format]} then { - test_follow_debuglink "--dwarf=follow-links --dwarf=info --dwarf=str" objdump.WK2 - test_follow_debuglink "--dwarf=follow-links --headers --wide" objdump.WK3 + test_follow_debuglink "--process-links --dwarf=info --dwarf=str" objdump.WK2 + test_follow_debuglink "--process-links --headers --wide" objdump.WK3 } # Test objdump output with start and stop address limits for the specified diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp index 775e782dfa..4884a5df40 100644 --- a/binutils/testsuite/binutils-all/readelf.exp +++ b/binutils/testsuite/binutils-all/readelf.exp @@ -118,8 +118,9 @@ proc readelf_test { options binary_file regexp_file } { } if { [regexp_diff readelf.out $srcdir/$subdir/$regexp_file] } then { + send_log [file_contents readelf.out] + send_log "\n" fail $testname - verbose "output is \n[file_contents readelf.out]" 2 return } @@ -526,7 +527,7 @@ if {![binutils_assemble $srcdir/$subdir/debuglink.s tmpdir/debuglink.o]} then { set tempfile2 [remote_download host tmpdir/linkdebug.debug] } - readelf_test {-wKis} $tempfile readelf.wKis + readelf_test "-wKis -P" $tempfile readelf.wKis } } diff --git a/binutils/testsuite/binutils-all/readelf.wKis b/binutils/testsuite/binutils-all/readelf.wKis index 5c7c0b25a5..a8ab25221b 100644 --- a/binutils/testsuite/binutils-all/readelf.wKis +++ b/binutils/testsuite/binutils-all/readelf.wKis @@ -1,6 +1,4 @@ #... -.*debuglink.o: Found separate debug info file:.*linkdebug.debug -#... Contents of the .debug_str section \(loaded from .*debuglink.o\): 0x00000000 73747269 6e672d31 00737472 696e672d string-1.string-