aboutsummaryrefslogtreecommitdiff
path: root/libbacktrace/elf.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-12-05 02:20:11 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-12-05 02:20:11 +0000
commit66ab583969c8fe833723703870a061b362de77fa (patch)
treeb56c972c897f04194bf100b70bf0a40a31e53468 /libbacktrace/elf.c
parent268209f3a0dc07fcf13534610447ab732742eb2f (diff)
downloadgcc-66ab583969c8fe833723703870a061b362de77fa.zip
gcc-66ab583969c8fe833723703870a061b362de77fa.tar.gz
gcc-66ab583969c8fe833723703870a061b362de77fa.tar.bz2
libbacktrace: simplify DWARF section handling
This is in preparation for adding DWARF 5 support. * internal.h (enum dwarf_section): Define. (struct dwarf_sections): Define. (backtrace_dwarf_add): Update declaration to replace specific section parameters with dwarf_sections parameter. * dwarf.c (struct dwarf_data): Replace specific section fields with dwarf_sections field. (read_attribute): Use dwarf_sections with altlink. (build_address_map): Replace specific section parameters with dwarf_sections parameter. Change all callers. (read_line_info): Use dwarf_sections with ddata. (read_referenced_name): Likewise. (add_function_ranges): Likewise. (read_function_entry): Likewise. (read_function_info): Likewise. (build_dwarf_data): Replace specific section parameters with dwarf_sections parameter. Change all callers. (backtrace_dwarf_add): Likewise. * elf.c (enum debug_section): Remove. (dwarf_section_names): Remove .zdebug names. (elf_add): Track zsections separately. Build dwarf_sections. * pecoff.c (enum debug_section): Remove. (struct debug_section_info): Remove data field. (coff_add): Build dwarf_sections. * xcoff.c (enum dwarf_section): Remove. Replace DWSECT_xxx references with DEBUG_xxx references. (xcoff_add): Build dwarf_sections. From-SVN: r278984
Diffstat (limited to 'libbacktrace/elf.c')
-rw-r--r--libbacktrace/elf.c113
1 files changed, 56 insertions, 57 deletions
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index f3988ec..89e0ab7 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -337,41 +337,15 @@ typedef struct
#define ELFCOMPRESS_ZLIB 1
-/* An index of ELF sections we care about. */
+/* Names of sections, indexed by enum dwarf_section in internal.h. */
-enum debug_section
-{
- DEBUG_INFO,
- DEBUG_LINE,
- DEBUG_ABBREV,
- DEBUG_RANGES,
- DEBUG_STR,
-
- /* The old style compressed sections. This list must correspond to
- the list of normal debug sections. */
- ZDEBUG_INFO,
- ZDEBUG_LINE,
- ZDEBUG_ABBREV,
- ZDEBUG_RANGES,
- ZDEBUG_STR,
-
- DEBUG_MAX
-};
-
-/* Names of sections, indexed by enum elf_section. */
-
-static const char * const debug_section_names[DEBUG_MAX] =
+static const char * const dwarf_section_names[DEBUG_MAX] =
{
".debug_info",
".debug_line",
".debug_abbrev",
".debug_ranges",
".debug_str",
- ".zdebug_info",
- ".zdebug_line",
- ".zdebug_abbrev",
- ".zdebug_ranges",
- ".zdebug_str"
};
/* Information we gather for the sections we care about. */
@@ -2661,6 +2635,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
unsigned int dynsym_shndx;
unsigned int i;
struct debug_section_info sections[DEBUG_MAX];
+ struct debug_section_info zsections[DEBUG_MAX];
struct backtrace_view symtab_view;
int symtab_view_valid;
struct backtrace_view strtab_view;
@@ -2685,6 +2660,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
unsigned int using_debug_view;
uint16_t *zdebug_table;
struct elf_ppc64_opd_data opd_data, *opd;
+ struct dwarf_sections dwarf_sections;
if (!debuginfo)
{
@@ -2825,6 +2801,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
dynsym_shndx = 0;
memset (sections, 0, sizeof sections);
+ memset (zsections, 0, sizeof zsections);
/* Look for the symbol table. */
for (i = 1; i < shnum; ++i)
@@ -2852,7 +2829,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
for (j = 0; j < (int) DEBUG_MAX; ++j)
{
- if (strcmp (name, debug_section_names[j]) == 0)
+ if (strcmp (name, dwarf_section_names[j]) == 0)
{
sections[j].offset = shdr->sh_offset;
sections[j].size = shdr->sh_size;
@@ -2861,6 +2838,19 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
}
}
+ if (name[0] == '.' && name[1] == 'z')
+ {
+ for (j = 0; j < (int) DEBUG_MAX; ++j)
+ {
+ if (strcmp (name + 2, dwarf_section_names[j] + 1) == 0)
+ {
+ zsections[j].offset = shdr->sh_offset;
+ zsections[j].size = shdr->sh_size;
+ break;
+ }
+ }
+ }
+
/* Read the build ID if present. This could check for any
SHT_NOTE section with the right note name and type, but gdb
looks for a specific section name. */
@@ -3132,7 +3122,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
}
/* Read all the debug sections in a single view, since they are
- probably adjacent in the file. We never release this view. */
+ probably adjacent in the file. If any of sections are
+ uncompressed, we never release this view. */
min_offset = 0;
max_offset = 0;
@@ -3140,13 +3131,22 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
{
off_t end;
- if (sections[i].size == 0)
- continue;
- if (min_offset == 0 || sections[i].offset < min_offset)
- min_offset = sections[i].offset;
- end = sections[i].offset + sections[i].size;
- if (end > max_offset)
- max_offset = end;
+ if (sections[i].size != 0)
+ {
+ if (min_offset == 0 || sections[i].offset < min_offset)
+ min_offset = sections[i].offset;
+ end = sections[i].offset + sections[i].size;
+ if (end > max_offset)
+ max_offset = end;
+ }
+ if (zsections[i].size != 0)
+ {
+ if (min_offset == 0 || zsections[i].offset < min_offset)
+ min_offset = zsections[i].offset;
+ end = zsections[i].offset + zsections[i].size;
+ if (end > max_offset)
+ max_offset = end;
+ }
}
if (min_offset == 0 || max_offset == 0)
{
@@ -3175,20 +3175,22 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
{
sections[i].data = ((const unsigned char *) debug_view.data
+ (sections[i].offset - min_offset));
- if (i < ZDEBUG_INFO)
- ++using_debug_view;
+ ++using_debug_view;
}
+
+ if (zsections[i].size == 0)
+ zsections[i].data = NULL;
+ else
+ zsections[i].data = ((const unsigned char *) debug_view.data
+ + (zsections[i].offset - min_offset));
}
/* Uncompress the old format (--compress-debug-sections=zlib-gnu). */
zdebug_table = NULL;
- for (i = 0; i < ZDEBUG_INFO; ++i)
+ for (i = 0; i < (int) DEBUG_MAX; ++i)
{
- struct debug_section_info *pz;
-
- pz = &sections[i + ZDEBUG_INFO - DEBUG_INFO];
- if (sections[i].size == 0 && pz->size > 0)
+ if (sections[i].size == 0 && zsections[i].size > 0)
{
unsigned char *uncompressed_data;
size_t uncompressed_size;
@@ -3204,7 +3206,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
uncompressed_data = NULL;
uncompressed_size = 0;
- if (!elf_uncompress_zdebug (state, pz->data, pz->size, zdebug_table,
+ if (!elf_uncompress_zdebug (state, zsections[i].data,
+ zsections[i].size, zdebug_table,
error_callback, data,
&uncompressed_data, &uncompressed_size))
goto fail;
@@ -3216,7 +3219,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
/* Uncompress the official ELF format
(--compress-debug-sections=zlib-gabi). */
- for (i = 0; i < ZDEBUG_INFO; ++i)
+ for (i = 0; i < (int) DEBUG_MAX; ++i)
{
unsigned char *uncompressed_data;
size_t uncompressed_size;
@@ -3256,17 +3259,13 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
debug_view_valid = 0;
}
- if (!backtrace_dwarf_add (state, base_address,
- sections[DEBUG_INFO].data,
- sections[DEBUG_INFO].size,
- sections[DEBUG_LINE].data,
- sections[DEBUG_LINE].size,
- sections[DEBUG_ABBREV].data,
- sections[DEBUG_ABBREV].size,
- sections[DEBUG_RANGES].data,
- sections[DEBUG_RANGES].size,
- sections[DEBUG_STR].data,
- sections[DEBUG_STR].size,
+ for (i = 0; i < (int) DEBUG_MAX; ++i)
+ {
+ dwarf_sections.data[i] = sections[i].data;
+ dwarf_sections.size[i] = sections[i].size;
+ }
+
+ if (!backtrace_dwarf_add (state, base_address, &dwarf_sections,
ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
fileline_altlink,
error_callback, data, fileline_fn,