mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-09 04:21:49 +08:00
dda8d76d0d
Hi Guys, I am applying the rather large patch attached to this email to enhance the readelf and objdump programs so that they now have the ability to follow links to separate debug info files. (As requested by PR 15152). So for example whereas before we had this output: $ readelf -wi main.exe Contents of the .debug_info section: [...] <15> DW_AT_comp_dir : (alt indirect string, offset: 0x30c) [...] With the new option enabled we get: $ readelf -wiK main.exe main.exe: Found separate debug info file: dwz.debug Contents of the .debug_info section (loaded from main.exe): [...] <15> DW_AT_comp_dir : (alt indirect string, offset: 0x30c) /home/nickc/Downloads/dwzm [...] The link following feature also means that we can get two lots of output if the same section exists in both the main file and the separate debug info file: $ readelf -wiK main.exe main.exe: Found separate debug info file: dwz.debug Contents of the .debug_info section (loaded from main.exe): [...] Contents of the .debug_info section (loaded from dwz.debug): [...] The patch also adds the ability to display the contents of debuglink sections: $ readelf -wk main.exe Contents of the .gnu_debugaltlink section: Separate debug info file: dwz.debug Build-ID (0x14 bytes): c4 a8 89 8d 64 cf 70 8a 35 68 21 f2 ed 24 45 3e 18 7a 7a 93 Naturally there are long versions of these options (=follow-links and =links). The documentation has been updated as well, and since both readelf and objdump use the same set of debug display options, I have moved the text into a separate file. There are also a couple of new binutils tests to exercise the new behaviour. There are a couple of missing features in the current patch however, although I do intend to address them in follow up submissions: Firstly the code does not check the build-id inside separate debug info files when it is searching for a file specified by a .gnu_debugaltlink section. It just assumes that if the file is there, then it contains the information being sought. Secondly I have not checked the DWARF-5 version of these link features, so there will probably be code to add there. Thirdly I have only implemented link following for the DW_FORM_GNU_strp_alt format. Other alternate formats (eg DW_FORM_GNU_ref_alt) have yet to be implemented. Lastly, whilst implementing this feature I found it necessary to move some of the global variables used by readelf (eg section_headers) into a structure that can be passed around. I have moved all of the global variables that were necessary to get the patch working, but I need to complete the operation and move the remaining, file-specific variables (eg dynamic_strings). Cheers Nick binutils PR 15152 * dwarf.h (enum dwarf_section_display_enum): Add gnu_debuglink, gnu_debugaltlink and separate_debug_str. (struct dwarf_section): Add filename field. Add prototypes for load_separate_debug_file, close_debug_file and open_debug_file. * dwarf.c (do_debug_links): New. (do_follow_links): New. (separate_debug_file, separate_debug_filename): New. (fetch_alt_indirect_string): New function. Retrieves a string from the debug string table in the separate debug info file. (read_and_display_attr_value): Use it with DW_FORM_GNU_strp_alt. (load_debug_section_with_follow): New function. Like load_debug_section, but if the first attempt fails, then tries again in the separate debug info file. (introduce): New function. (process_debug_info): Use load_debug_section_with_follow and introduce. (load_debug_info): Likewise. (display_debug_lines_raw): Likewise. (display_debug_lines_decoded): Likewise. (display_debug_macinfo): Likewise. (display_debug_macro): Likewise. (display_debug_abbrev): Likewise. (display_debug_loc): Likewise. (display_debug_str): Likewise. (display_debug_aranges): Likewise. (display_debug_addr); Likewise. (display_debug_frames): Likewise. (display_gdb_index): Likewise. (process_cu_tu_index): Likewise. (load_cu_tu_indexes): Likewise. (display_debug_links): New function. Displays the contents of a .gnu_debuglink or .gnu_debugaltlink section. (calc_gnu_debuglink_ctc32):New function. Calculates a CRC32 value. (check_gnu_debuglink): New function. Checks the CRC of a potential separate debug info file. (parse_gnu_debuglink): New function. Reads a CRC value out of a .gnu_debuglink section. (check_gnu_debugaltlink): New function. (parse_gnu_debugaltlink): New function. Reads the build-id value out of a .gnu_debugaltlink section. (load_separate_debug_info): New function. Finds and loads a separate debug info file. (load_separate_debug_file): New function. Attempts to find and follow a link to a separate debug info file. (free_debug_memory): Free the separate debug info file information. (opts_table): Add "follow-links" and "links". (dwarf_select_sections_by_letters): Add "k" and "K". (debug_displays): Reformat. Add .gnu-debuglink and .gnu_debugaltlink. Add an extra entry for .debug_str in a separate debug info file. * doc/binutils.texi: Move description of debug dump features common to both readelf and objdump into... * objdump.c (usage): Add -Wk and -WK. (load_specific_debug_section): Initialise the filename field in the dwarf_section structure. (close_debug_file): New function. (open_debug_file): New function. (dump_dwarf): Load and dump the separate debug info sections. * readelf.c (struct filedata): New structure. Contains various variables that used to be global: (current_file_size, string_table, string_table_length, elf_header) (section_headers, program_headers, dump_sects, num_dump_sects): Move into filedata structure. (cmdline): New global variable. Contains list of sections to dump by number, as specified on the command line. Add filedata parameter to most functions. (load_debug_section): Load the string table if it has not already been retrieved. (close_file): New function. (close_debug_file): New function. (open_file): New function. (open_debug_file): New function. (process_object): Process sections in any separate debug info files. * doc/debug.options.texi: New file. Add description of =links and =follow-links options. * NEWS: Mention the new feature. * elfcomm.c: Have the byte gte functions take a const pointer. * elfcomm.h: Update prototypes. * testsuite/binutils-all/dw5.W: Update expected output. * testsuite/binutils-all/objdump.WL: Update expected output. * testsuite/binutils-all/objdump.exp: Add test of -WK and -Wk. * testsuite/binutils-all/readelf.exp: Add test of -wK and -wk. * testsuite/binutils-all/readelf.k: New file. * testsuite/binutils-all/objdump.Wk: New file. * testsuite/binutils-all/objdump.WK2: New file. * testsuite/binutils-all/linkdebug.s: New file. * testsuite/binutils-all/debuglink.s: New file. gas * testsuite/gas/avr/large-debug-line-table.d: Update expected output. * testsuite/gas/elf/dwarf2-11.d: Likewise. * testsuite/gas/elf/dwarf2-12.d: Likewise. * testsuite/gas/elf/dwarf2-13.d: Likewise. * testsuite/gas/elf/dwarf2-14.d: Likewise. * testsuite/gas/elf/dwarf2-15.d: Likewise. * testsuite/gas/elf/dwarf2-16.d: Likewise. * testsuite/gas/elf/dwarf2-17.d: Likewise. * testsuite/gas/elf/dwarf2-18.d: Likewise. * testsuite/gas/elf/dwarf2-5.d: Likewise. * testsuite/gas/elf/dwarf2-6.d: Likewise. * testsuite/gas/elf/dwarf2-7.d: Likewise. ld * testsuite/ld-avr/gc-section-debugline.d: Update expected output.
105 lines
4.3 KiB
C
105 lines
4.3 KiB
C
/* elfcomm.h -- include file of common code for ELF format file.
|
||
Copyright (C) 2010-2017 Free Software Foundation, Inc.
|
||
|
||
Originally developed by Eric Youngdale <eric@andante.jic.com>
|
||
Modifications by Nick Clifton <nickc@redhat.com>
|
||
|
||
This file is part of GNU Binutils.
|
||
|
||
This program is free software; you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation; either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with this program; if not, write to the Free Software
|
||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||
02110-1301, USA. */
|
||
|
||
#ifndef _ELFCOMM_H
|
||
#define _ELFCOMM_H
|
||
|
||
#include "aout/ar.h"
|
||
|
||
void error (const char *, ...) ATTRIBUTE_PRINTF_1;
|
||
void warn (const char *, ...) ATTRIBUTE_PRINTF_1;
|
||
|
||
typedef unsigned HOST_WIDEST_INT elf_vma;
|
||
|
||
extern void (*byte_put) (unsigned char *, elf_vma, int);
|
||
extern void byte_put_little_endian (unsigned char *, elf_vma, int);
|
||
extern void byte_put_big_endian (unsigned char *, elf_vma, int);
|
||
|
||
extern elf_vma (*byte_get) (const unsigned char *, int);
|
||
extern elf_vma byte_get_signed (const unsigned char *, int);
|
||
extern elf_vma byte_get_little_endian (const unsigned char *, int);
|
||
extern elf_vma byte_get_big_endian (const unsigned char *, int);
|
||
extern void byte_get_64 (const unsigned char *, elf_vma *, elf_vma *);
|
||
|
||
#define BYTE_PUT(field, val) byte_put (field, val, sizeof (field))
|
||
#define BYTE_GET(field) byte_get (field, sizeof (field))
|
||
#define BYTE_GET_SIGNED(field) byte_get_signed (field, sizeof (field))
|
||
|
||
/* This is just a bit of syntatic sugar. */
|
||
#define streq(a,b) (strcmp ((a), (b)) == 0)
|
||
#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
|
||
#define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
|
||
|
||
/* Structure to hold information about an archive file. */
|
||
|
||
struct archive_info
|
||
{
|
||
char * file_name; /* Archive file name. */
|
||
FILE * file; /* Open file descriptor. */
|
||
elf_vma index_num; /* Number of symbols in table. */
|
||
elf_vma * index_array; /* The array of member offsets. */
|
||
char * sym_table; /* The symbol table. */
|
||
unsigned long sym_size; /* Size of the symbol table. */
|
||
char * longnames; /* The long file names table. */
|
||
unsigned long longnames_size; /* Size of the long file names table. */
|
||
unsigned long nested_member_origin; /* Origin in the nested archive of the current member. */
|
||
unsigned long next_arhdr_offset; /* Offset of the next archive header. */
|
||
bfd_boolean is_thin_archive; /* TRUE if this is a thin archive. */
|
||
bfd_boolean uses_64bit_indicies; /* TRUE if the index table uses 64bit entries. */
|
||
struct ar_hdr arhdr; /* Current archive header. */
|
||
};
|
||
|
||
/* Return the path name for a proxy entry in a thin archive. */
|
||
extern char *adjust_relative_path (const char *, const char *, unsigned long);
|
||
|
||
/* Read the symbol table and long-name table from an archive. */
|
||
extern int setup_archive (struct archive_info *, const char *, FILE *,
|
||
bfd_boolean, bfd_boolean);
|
||
|
||
/* Open and setup a nested archive, if not already open. */
|
||
extern int setup_nested_archive (struct archive_info *, const char *);
|
||
|
||
/* Release the memory used for the archive information. */
|
||
extern void release_archive (struct archive_info *);
|
||
|
||
/* Get the name of an archive member from the current archive header. */
|
||
|
||
extern char *get_archive_member_name (struct archive_info *,
|
||
struct archive_info *);
|
||
|
||
/* Get the name of an archive member at a given offset within an
|
||
archive. */
|
||
|
||
extern char *get_archive_member_name_at (struct archive_info *,
|
||
unsigned long,
|
||
struct archive_info *);
|
||
|
||
/* Construct a string showing the name of the archive member, qualified
|
||
with the name of the containing archive file. */
|
||
|
||
extern char *make_qualified_name (struct archive_info *,
|
||
struct archive_info *,
|
||
const char *);
|
||
|
||
#endif /* _ELFCOMM_H */
|