Commit 66ab5839 by Ian Lance Taylor Committed by Ian Lance Taylor

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
parent 268209f3
2019-12-04 Ian Lance Taylor <iant@golang.org>
* 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.
2019-09-27 Maciej W. Rozycki <macro@wdc.com> 2019-09-27 Maciej W. Rozycki <macro@wdc.com>
* configure: Regenerate. * configure: Regenerate.
......
...@@ -373,18 +373,8 @@ struct dwarf_data ...@@ -373,18 +373,8 @@ struct dwarf_data
struct unit **units; struct unit **units;
/* Number of units in the list. */ /* Number of units in the list. */
size_t units_count; size_t units_count;
/* The unparsed .debug_info section. */ /* The unparsed DWARF debug data. */
const unsigned char *dwarf_info; struct dwarf_sections dwarf_sections;
size_t dwarf_info_size;
/* The unparsed .debug_line section. */
const unsigned char *dwarf_line;
size_t dwarf_line_size;
/* The unparsed .debug_ranges section. */
const unsigned char *dwarf_ranges;
size_t dwarf_ranges_size;
/* The unparsed .debug_str section. */
const unsigned char *dwarf_str;
size_t dwarf_str_size;
/* Whether the data is big-endian or not. */ /* Whether the data is big-endian or not. */
int is_bigendian; int is_bigendian;
/* A vector used for function addresses. We keep this here so that /* A vector used for function addresses. We keep this here so that
...@@ -871,13 +861,14 @@ read_attribute (enum dwarf_form form, struct dwarf_buf *buf, ...@@ -871,13 +861,14 @@ read_attribute (enum dwarf_form form, struct dwarf_buf *buf,
val->encoding = ATTR_VAL_NONE; val->encoding = ATTR_VAL_NONE;
return 1; return 1;
} }
if (offset >= altlink->dwarf_str_size) if (offset >= altlink->dwarf_sections.size[DEBUG_STR])
{ {
dwarf_buf_error (buf, "DW_FORM_GNU_strp_alt out of range"); dwarf_buf_error (buf, "DW_FORM_GNU_strp_alt out of range");
return 0; return 0;
} }
val->encoding = ATTR_VAL_STRING; val->encoding = ATTR_VAL_STRING;
val->u.string = (const char *) altlink->dwarf_str + offset; val->u.string =
(const char *) altlink->dwarf_sections.data[DEBUG_STR] + offset;
return 1; return 1;
} }
default: default:
...@@ -1499,10 +1490,7 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, ...@@ -1499,10 +1490,7 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
static int static int
build_address_map (struct backtrace_state *state, uintptr_t base_address, build_address_map (struct backtrace_state *state, uintptr_t base_address,
const unsigned char *dwarf_info, size_t dwarf_info_size, const struct dwarf_sections *dwarf_sections,
const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size,
const unsigned char *dwarf_ranges, size_t dwarf_ranges_size,
const unsigned char *dwarf_str, size_t dwarf_str_size,
int is_bigendian, struct dwarf_data *altlink, int is_bigendian, struct dwarf_data *altlink,
backtrace_error_callback error_callback, void *data, backtrace_error_callback error_callback, void *data,
struct unit_addrs_vector *addrs, struct unit_addrs_vector *addrs,
...@@ -1525,9 +1513,9 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address, ...@@ -1525,9 +1513,9 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
not sure why. */ not sure why. */
info.name = ".debug_info"; info.name = ".debug_info";
info.start = dwarf_info; info.start = dwarf_sections->data[DEBUG_INFO];
info.buf = dwarf_info; info.buf = info.start;
info.left = dwarf_info_size; info.left = dwarf_sections->size[DEBUG_INFO];
info.is_bigendian = is_bigendian; info.is_bigendian = is_bigendian;
info.error_callback = error_callback; info.error_callback = error_callback;
info.data = data; info.data = data;
...@@ -1583,7 +1571,9 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address, ...@@ -1583,7 +1571,9 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
memset (&u->abbrevs, 0, sizeof u->abbrevs); memset (&u->abbrevs, 0, sizeof u->abbrevs);
abbrev_offset = read_offset (&unit_buf, is_dwarf64); abbrev_offset = read_offset (&unit_buf, is_dwarf64);
if (!read_abbrevs (state, abbrev_offset, dwarf_abbrev, dwarf_abbrev_size, if (!read_abbrevs (state, abbrev_offset,
dwarf_sections->data[DEBUG_ABBREV],
dwarf_sections->size[DEBUG_ABBREV],
is_bigendian, error_callback, data, &u->abbrevs)) is_bigendian, error_callback, data, &u->abbrevs))
goto fail; goto fail;
...@@ -1610,8 +1600,10 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address, ...@@ -1610,8 +1600,10 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
u->function_addrs_count = 0; u->function_addrs_count = 0;
if (!find_address_ranges (state, base_address, &unit_buf, if (!find_address_ranges (state, base_address, &unit_buf,
dwarf_str, dwarf_str_size, dwarf_sections->data[DEBUG_STR],
dwarf_ranges, dwarf_ranges_size, dwarf_sections->size[DEBUG_STR],
dwarf_sections->data[DEBUG_RANGES],
dwarf_sections->size[DEBUG_RANGES],
is_bigendian, altlink, error_callback, data, is_bigendian, altlink, error_callback, data,
u, addrs, &unit_tag)) u, addrs, &unit_tag))
goto fail; goto fail;
...@@ -2089,16 +2081,16 @@ read_line_info (struct backtrace_state *state, struct dwarf_data *ddata, ...@@ -2089,16 +2081,16 @@ read_line_info (struct backtrace_state *state, struct dwarf_data *ddata,
memset (hdr, 0, sizeof *hdr); memset (hdr, 0, sizeof *hdr);
if (u->lineoff != (off_t) (size_t) u->lineoff if (u->lineoff != (off_t) (size_t) u->lineoff
|| (size_t) u->lineoff >= ddata->dwarf_line_size) || (size_t) u->lineoff >= ddata->dwarf_sections.size[DEBUG_LINE])
{ {
error_callback (data, "unit line offset out of range", 0); error_callback (data, "unit line offset out of range", 0);
goto fail; goto fail;
} }
line_buf.name = ".debug_line"; line_buf.name = ".debug_line";
line_buf.start = ddata->dwarf_line; line_buf.start = ddata->dwarf_sections.data[DEBUG_LINE];
line_buf.buf = ddata->dwarf_line + u->lineoff; line_buf.buf = ddata->dwarf_sections.data[DEBUG_LINE] + u->lineoff;
line_buf.left = ddata->dwarf_line_size - u->lineoff; line_buf.left = ddata->dwarf_sections.size[DEBUG_LINE] - u->lineoff;
line_buf.is_bigendian = ddata->is_bigendian; line_buf.is_bigendian = ddata->is_bigendian;
line_buf.error_callback = error_callback; line_buf.error_callback = error_callback;
line_buf.data = data; line_buf.data = data;
...@@ -2241,7 +2233,7 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u, ...@@ -2241,7 +2233,7 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u,
offset -= u->unit_data_offset; offset -= u->unit_data_offset;
unit_buf.name = ".debug_info"; unit_buf.name = ".debug_info";
unit_buf.start = ddata->dwarf_info; unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO];
unit_buf.buf = u->unit_data + offset; unit_buf.buf = u->unit_data + offset;
unit_buf.left = u->unit_data_len - offset; unit_buf.left = u->unit_data_len - offset;
unit_buf.is_bigendian = ddata->is_bigendian; unit_buf.is_bigendian = ddata->is_bigendian;
...@@ -2267,7 +2259,8 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u, ...@@ -2267,7 +2259,8 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u,
if (!read_attribute (abbrev->attrs[i].form, &unit_buf, if (!read_attribute (abbrev->attrs[i].form, &unit_buf,
u->is_dwarf64, u->version, u->addrsize, u->is_dwarf64, u->version, u->addrsize,
ddata->dwarf_str, ddata->dwarf_str_size, ddata->dwarf_sections.data[DEBUG_STR],
ddata->dwarf_sections.size[DEBUG_STR],
ddata->altlink, &val)) ddata->altlink, &val))
return NULL; return NULL;
...@@ -2364,16 +2357,16 @@ add_function_ranges (struct backtrace_state *state, struct dwarf_data *ddata, ...@@ -2364,16 +2357,16 @@ add_function_ranges (struct backtrace_state *state, struct dwarf_data *ddata,
{ {
struct dwarf_buf ranges_buf; struct dwarf_buf ranges_buf;
if (ranges >= ddata->dwarf_ranges_size) if (ranges >= ddata->dwarf_sections.size[DEBUG_RANGES])
{ {
error_callback (data, "function ranges offset out of range", 0); error_callback (data, "function ranges offset out of range", 0);
return 0; return 0;
} }
ranges_buf.name = ".debug_ranges"; ranges_buf.name = ".debug_ranges";
ranges_buf.start = ddata->dwarf_ranges; ranges_buf.start = ddata->dwarf_sections.data[DEBUG_RANGES];
ranges_buf.buf = ddata->dwarf_ranges + ranges; ranges_buf.buf = ddata->dwarf_sections.data[DEBUG_RANGES] + ranges;
ranges_buf.left = ddata->dwarf_ranges_size - ranges; ranges_buf.left = ddata->dwarf_sections.size[DEBUG_RANGES] - ranges;
ranges_buf.is_bigendian = ddata->is_bigendian; ranges_buf.is_bigendian = ddata->is_bigendian;
ranges_buf.error_callback = error_callback; ranges_buf.error_callback = error_callback;
ranges_buf.data = data; ranges_buf.data = data;
...@@ -2479,7 +2472,8 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata, ...@@ -2479,7 +2472,8 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
if (!read_attribute (abbrev->attrs[i].form, unit_buf, if (!read_attribute (abbrev->attrs[i].form, unit_buf,
u->is_dwarf64, u->version, u->addrsize, u->is_dwarf64, u->version, u->addrsize,
ddata->dwarf_str, ddata->dwarf_str_size, ddata->dwarf_sections.data[DEBUG_STR],
ddata->dwarf_sections.size[DEBUG_STR],
ddata->altlink, &val)) ddata->altlink, &val))
return 0; return 0;
...@@ -2698,7 +2692,7 @@ read_function_info (struct backtrace_state *state, struct dwarf_data *ddata, ...@@ -2698,7 +2692,7 @@ read_function_info (struct backtrace_state *state, struct dwarf_data *ddata,
} }
unit_buf.name = ".debug_info"; unit_buf.name = ".debug_info";
unit_buf.start = ddata->dwarf_info; unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO];
unit_buf.buf = u->unit_data; unit_buf.buf = u->unit_data;
unit_buf.left = u->unit_data_len; unit_buf.left = u->unit_data_len;
unit_buf.is_bigendian = ddata->is_bigendian; unit_buf.is_bigendian = ddata->is_bigendian;
...@@ -3077,16 +3071,7 @@ dwarf_fileline (struct backtrace_state *state, uintptr_t pc, ...@@ -3077,16 +3071,7 @@ dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
static struct dwarf_data * static struct dwarf_data *
build_dwarf_data (struct backtrace_state *state, build_dwarf_data (struct backtrace_state *state,
uintptr_t base_address, uintptr_t base_address,
const unsigned char *dwarf_info, const struct dwarf_sections *dwarf_sections,
size_t dwarf_info_size,
const unsigned char *dwarf_line,
size_t dwarf_line_size,
const unsigned char *dwarf_abbrev,
size_t dwarf_abbrev_size,
const unsigned char *dwarf_ranges,
size_t dwarf_ranges_size,
const unsigned char *dwarf_str,
size_t dwarf_str_size,
int is_bigendian, int is_bigendian,
struct dwarf_data *altlink, struct dwarf_data *altlink,
backtrace_error_callback error_callback, backtrace_error_callback error_callback,
...@@ -3100,11 +3085,9 @@ build_dwarf_data (struct backtrace_state *state, ...@@ -3100,11 +3085,9 @@ build_dwarf_data (struct backtrace_state *state,
size_t units_count; size_t units_count;
struct dwarf_data *fdata; struct dwarf_data *fdata;
if (!build_address_map (state, base_address, dwarf_info, dwarf_info_size, if (!build_address_map (state, base_address, dwarf_sections, is_bigendian,
dwarf_abbrev, dwarf_abbrev_size, dwarf_ranges, altlink, error_callback, data, &addrs_vec,
dwarf_ranges_size, dwarf_str, dwarf_str_size, &units_vec))
is_bigendian, altlink, error_callback, data,
&addrs_vec, &units_vec))
return NULL; return NULL;
if (!backtrace_vector_release (state, &addrs_vec.vec, error_callback, data)) if (!backtrace_vector_release (state, &addrs_vec.vec, error_callback, data))
...@@ -3132,14 +3115,7 @@ build_dwarf_data (struct backtrace_state *state, ...@@ -3132,14 +3115,7 @@ build_dwarf_data (struct backtrace_state *state,
fdata->addrs_count = addrs_count; fdata->addrs_count = addrs_count;
fdata->units = units; fdata->units = units;
fdata->units_count = units_count; fdata->units_count = units_count;
fdata->dwarf_info = dwarf_info; fdata->dwarf_sections = *dwarf_sections;
fdata->dwarf_info_size = dwarf_info_size;
fdata->dwarf_line = dwarf_line;
fdata->dwarf_line_size = dwarf_line_size;
fdata->dwarf_ranges = dwarf_ranges;
fdata->dwarf_ranges_size = dwarf_ranges_size;
fdata->dwarf_str = dwarf_str;
fdata->dwarf_str_size = dwarf_str_size;
fdata->is_bigendian = is_bigendian; fdata->is_bigendian = is_bigendian;
memset (&fdata->fvec, 0, sizeof fdata->fvec); memset (&fdata->fvec, 0, sizeof fdata->fvec);
...@@ -3153,16 +3129,7 @@ build_dwarf_data (struct backtrace_state *state, ...@@ -3153,16 +3129,7 @@ build_dwarf_data (struct backtrace_state *state,
int int
backtrace_dwarf_add (struct backtrace_state *state, backtrace_dwarf_add (struct backtrace_state *state,
uintptr_t base_address, uintptr_t base_address,
const unsigned char *dwarf_info, const struct dwarf_sections *dwarf_sections,
size_t dwarf_info_size,
const unsigned char *dwarf_line,
size_t dwarf_line_size,
const unsigned char *dwarf_abbrev,
size_t dwarf_abbrev_size,
const unsigned char *dwarf_ranges,
size_t dwarf_ranges_size,
const unsigned char *dwarf_str,
size_t dwarf_str_size,
int is_bigendian, int is_bigendian,
struct dwarf_data *fileline_altlink, struct dwarf_data *fileline_altlink,
backtrace_error_callback error_callback, backtrace_error_callback error_callback,
...@@ -3171,10 +3138,7 @@ backtrace_dwarf_add (struct backtrace_state *state, ...@@ -3171,10 +3138,7 @@ backtrace_dwarf_add (struct backtrace_state *state,
{ {
struct dwarf_data *fdata; struct dwarf_data *fdata;
fdata = build_dwarf_data (state, base_address, dwarf_info, dwarf_info_size, fdata = build_dwarf_data (state, base_address, dwarf_sections, is_bigendian,
dwarf_line, dwarf_line_size, dwarf_abbrev,
dwarf_abbrev_size, dwarf_ranges, dwarf_ranges_size,
dwarf_str, dwarf_str_size, is_bigendian,
fileline_altlink, error_callback, data); fileline_altlink, error_callback, data);
if (fdata == NULL) if (fdata == NULL)
return 0; return 0;
......
...@@ -337,41 +337,15 @@ typedef struct ...@@ -337,41 +337,15 @@ typedef struct
#define ELFCOMPRESS_ZLIB 1 #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 static const char * const dwarf_section_names[DEBUG_MAX] =
{
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] =
{ {
".debug_info", ".debug_info",
".debug_line", ".debug_line",
".debug_abbrev", ".debug_abbrev",
".debug_ranges", ".debug_ranges",
".debug_str", ".debug_str",
".zdebug_info",
".zdebug_line",
".zdebug_abbrev",
".zdebug_ranges",
".zdebug_str"
}; };
/* Information we gather for the sections we care about. */ /* Information we gather for the sections we care about. */
...@@ -2661,6 +2635,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, ...@@ -2661,6 +2635,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
unsigned int dynsym_shndx; unsigned int dynsym_shndx;
unsigned int i; unsigned int i;
struct debug_section_info sections[DEBUG_MAX]; struct debug_section_info sections[DEBUG_MAX];
struct debug_section_info zsections[DEBUG_MAX];
struct backtrace_view symtab_view; struct backtrace_view symtab_view;
int symtab_view_valid; int symtab_view_valid;
struct backtrace_view strtab_view; struct backtrace_view strtab_view;
...@@ -2685,6 +2660,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, ...@@ -2685,6 +2660,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
unsigned int using_debug_view; unsigned int using_debug_view;
uint16_t *zdebug_table; uint16_t *zdebug_table;
struct elf_ppc64_opd_data opd_data, *opd; struct elf_ppc64_opd_data opd_data, *opd;
struct dwarf_sections dwarf_sections;
if (!debuginfo) if (!debuginfo)
{ {
...@@ -2825,6 +2801,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, ...@@ -2825,6 +2801,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
dynsym_shndx = 0; dynsym_shndx = 0;
memset (sections, 0, sizeof sections); memset (sections, 0, sizeof sections);
memset (zsections, 0, sizeof zsections);
/* Look for the symbol table. */ /* Look for the symbol table. */
for (i = 1; i < shnum; ++i) for (i = 1; i < shnum; ++i)
...@@ -2852,7 +2829,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, ...@@ -2852,7 +2829,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
for (j = 0; j < (int) DEBUG_MAX; ++j) 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].offset = shdr->sh_offset;
sections[j].size = shdr->sh_size; sections[j].size = shdr->sh_size;
...@@ -2861,6 +2838,19 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, ...@@ -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 /* Read the build ID if present. This could check for any
SHT_NOTE section with the right note name and type, but gdb SHT_NOTE section with the right note name and type, but gdb
looks for a specific section name. */ looks for a specific section name. */
...@@ -3132,7 +3122,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, ...@@ -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 /* 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; min_offset = 0;
max_offset = 0; max_offset = 0;
...@@ -3140,13 +3131,22 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, ...@@ -3140,13 +3131,22 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
{ {
off_t end; off_t end;
if (sections[i].size == 0) if (sections[i].size != 0)
continue; {
if (min_offset == 0 || sections[i].offset < min_offset) if (min_offset == 0 || sections[i].offset < min_offset)
min_offset = sections[i].offset; min_offset = sections[i].offset;
end = sections[i].offset + sections[i].size; end = sections[i].offset + sections[i].size;
if (end > max_offset) if (end > max_offset)
max_offset = end; 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) if (min_offset == 0 || max_offset == 0)
{ {
...@@ -3175,20 +3175,22 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, ...@@ -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].data = ((const unsigned char *) debug_view.data
+ (sections[i].offset - min_offset)); + (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). */ /* Uncompress the old format (--compress-debug-sections=zlib-gnu). */
zdebug_table = NULL; zdebug_table = NULL;
for (i = 0; i < ZDEBUG_INFO; ++i) for (i = 0; i < (int) DEBUG_MAX; ++i)
{ {
struct debug_section_info *pz; if (sections[i].size == 0 && zsections[i].size > 0)
pz = &sections[i + ZDEBUG_INFO - DEBUG_INFO];
if (sections[i].size == 0 && pz->size > 0)
{ {
unsigned char *uncompressed_data; unsigned char *uncompressed_data;
size_t uncompressed_size; size_t uncompressed_size;
...@@ -3204,7 +3206,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, ...@@ -3204,7 +3206,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
uncompressed_data = NULL; uncompressed_data = NULL;
uncompressed_size = 0; 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, error_callback, data,
&uncompressed_data, &uncompressed_size)) &uncompressed_data, &uncompressed_size))
goto fail; goto fail;
...@@ -3216,7 +3219,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, ...@@ -3216,7 +3219,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
/* Uncompress the official ELF format /* Uncompress the official ELF format
(--compress-debug-sections=zlib-gabi). */ (--compress-debug-sections=zlib-gabi). */
for (i = 0; i < ZDEBUG_INFO; ++i) for (i = 0; i < (int) DEBUG_MAX; ++i)
{ {
unsigned char *uncompressed_data; unsigned char *uncompressed_data;
size_t uncompressed_size; size_t uncompressed_size;
...@@ -3256,17 +3259,13 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, ...@@ -3256,17 +3259,13 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
debug_view_valid = 0; debug_view_valid = 0;
} }
if (!backtrace_dwarf_add (state, base_address, for (i = 0; i < (int) DEBUG_MAX; ++i)
sections[DEBUG_INFO].data, {
sections[DEBUG_INFO].size, dwarf_sections.data[i] = sections[i].data;
sections[DEBUG_LINE].data, dwarf_sections.size[i] = sections[i].size;
sections[DEBUG_LINE].size, }
sections[DEBUG_ABBREV].data,
sections[DEBUG_ABBREV].size, if (!backtrace_dwarf_add (state, base_address, &dwarf_sections,
sections[DEBUG_RANGES].data,
sections[DEBUG_RANGES].size,
sections[DEBUG_STR].data,
sections[DEBUG_STR].size,
ehdr.e_ident[EI_DATA] == ELFDATA2MSB, ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
fileline_altlink, fileline_altlink,
error_callback, data, fileline_fn, error_callback, data, fileline_fn,
......
...@@ -286,22 +286,36 @@ extern int backtrace_initialize (struct backtrace_state *state, ...@@ -286,22 +286,36 @@ extern int backtrace_initialize (struct backtrace_state *state,
void *data, void *data,
fileline *fileline_fn); fileline *fileline_fn);
/* An enum for the DWARF sections we care about. */
enum dwarf_section
{
DEBUG_INFO,
DEBUG_LINE,
DEBUG_ABBREV,
DEBUG_RANGES,
DEBUG_STR,
DEBUG_MAX
};
/* Data for the DWARF sections we care about. */
struct dwarf_sections
{
const unsigned char *data[DEBUG_MAX];
size_t size[DEBUG_MAX];
};
/* DWARF data read from a file, used for .gnu_debugaltlink. */
struct dwarf_data; struct dwarf_data;
/* Add file/line information for a DWARF module. */ /* Add file/line information for a DWARF module. */
extern int backtrace_dwarf_add (struct backtrace_state *state, extern int backtrace_dwarf_add (struct backtrace_state *state,
uintptr_t base_address, uintptr_t base_address,
const unsigned char* dwarf_info, const struct dwarf_sections *dwarf_sections,
size_t dwarf_info_size,
const unsigned char *dwarf_line,
size_t dwarf_line_size,
const unsigned char *dwarf_abbrev,
size_t dwarf_abbrev_size,
const unsigned char *dwarf_ranges,
size_t dwarf_range_size,
const unsigned char *dwarf_str,
size_t dwarf_str_size,
int is_bigendian, int is_bigendian,
struct dwarf_data *fileline_altlink, struct dwarf_data *fileline_altlink,
backtrace_error_callback error_callback, backtrace_error_callback error_callback,
......
...@@ -133,19 +133,7 @@ typedef struct { ...@@ -133,19 +133,7 @@ typedef struct {
uint16_t sc; uint16_t sc;
} b_coff_internal_symbol; } b_coff_internal_symbol;
/* An index of 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,
DEBUG_MAX
};
/* Names of sections, indexed by enum debug_section. */
static const char * const debug_section_names[DEBUG_MAX] = static const char * const debug_section_names[DEBUG_MAX] =
{ {
...@@ -164,8 +152,6 @@ struct debug_section_info ...@@ -164,8 +152,6 @@ struct debug_section_info
off_t offset; off_t offset;
/* Section size. */ /* Section size. */
size_t size; size_t size;
/* Section contents, after read from file. */
const unsigned char *data;
}; };
/* Information we keep for an coff symbol. */ /* Information we keep for an coff symbol. */
...@@ -616,6 +602,7 @@ coff_add (struct backtrace_state *state, int descriptor, ...@@ -616,6 +602,7 @@ coff_add (struct backtrace_state *state, int descriptor,
struct backtrace_view debug_view; struct backtrace_view debug_view;
int debug_view_valid; int debug_view_valid;
uintptr_t image_base; uintptr_t image_base;
struct dwarf_sections dwarf_sections;
*found_sym = 0; *found_sym = 0;
*found_dwarf = 0; *found_dwarf = 0;
...@@ -848,28 +835,20 @@ coff_add (struct backtrace_state *state, int descriptor, ...@@ -848,28 +835,20 @@ coff_add (struct backtrace_state *state, int descriptor,
for (i = 0; i < (int) DEBUG_MAX; ++i) for (i = 0; i < (int) DEBUG_MAX; ++i)
{ {
if (sections[i].size == 0) size_t size = sections[i].size;
sections[i].data = NULL; dwarf_sections.size[i] = size;
if (size == 0)
dwarf_sections.data[i] = NULL;
else else
sections[i].data = ((const unsigned char *) debug_view.data dwarf_sections.data[i] = ((const unsigned char *) debug_view.data
+ (sections[i].offset - min_offset)); + (sections[i].offset - min_offset));
} }
if (!backtrace_dwarf_add (state, /* base_address */ 0, if (!backtrace_dwarf_add (state, /* base_address */ 0, &dwarf_sections,
sections[DEBUG_INFO].data, 0, /* FIXME: is_bigendian */
sections[DEBUG_INFO].size, NULL, /* altlink */
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,
0, /* FIXME */
NULL,
error_callback, data, fileline_fn, error_callback, data, fileline_fn,
NULL)) NULL /* returned fileline_entry */))
goto fail; goto fail;
*found_dwarf = 1; *found_dwarf = 1;
......
...@@ -387,18 +387,6 @@ struct xcoff_fileline_data ...@@ -387,18 +387,6 @@ struct xcoff_fileline_data
uintptr_t base_address; uintptr_t base_address;
}; };
/* An index of DWARF sections we care about. */
enum dwarf_section
{
DWSECT_INFO,
DWSECT_LINE,
DWSECT_ABBREV,
DWSECT_RANGES,
DWSECT_STR,
DWSECT_MAX
};
/* Information we gather for the DWARF sections we care about. */ /* Information we gather for the DWARF sections we care about. */
struct dwsect_info struct dwsect_info
...@@ -1100,7 +1088,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset, ...@@ -1100,7 +1088,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
off_t str_off; off_t str_off;
off_t min_offset; off_t min_offset;
off_t max_offset; off_t max_offset;
struct dwsect_info dwsect[DWSECT_MAX]; struct dwsect_info dwsect[DEBUG_MAX];
size_t sects_size; size_t sects_size;
size_t syms_size; size_t syms_size;
int32_t str_size; int32_t str_size;
...@@ -1111,6 +1099,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset, ...@@ -1111,6 +1099,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
int dwarf_view_valid; int dwarf_view_valid;
int magic_ok; int magic_ok;
int i; int i;
struct dwarf_sections dwarf_sections;
*found_sym = 0; *found_sym = 0;
...@@ -1255,19 +1244,19 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset, ...@@ -1255,19 +1244,19 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
switch (sects[i].s_flags & 0xffff0000) switch (sects[i].s_flags & 0xffff0000)
{ {
case SSUBTYP_DWINFO: case SSUBTYP_DWINFO:
idx = DWSECT_INFO; idx = DEBUG_INFO;
break; break;
case SSUBTYP_DWLINE: case SSUBTYP_DWLINE:
idx = DWSECT_LINE; idx = DEBUG_LINE;
break; break;
case SSUBTYP_DWABREV: case SSUBTYP_DWABREV:
idx = DWSECT_ABBREV; idx = DEBUG_ABBREV;
break; break;
case SSUBTYP_DWARNGE: case SSUBTYP_DWARNGE:
idx = DWSECT_RANGES; idx = DEBUG_RANGES;
break; break;
case SSUBTYP_DWSTR: case SSUBTYP_DWSTR:
idx = DWSECT_STR; idx = DEBUG_STR;
break; break;
default: default:
continue; continue;
...@@ -1288,7 +1277,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset, ...@@ -1288,7 +1277,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
goto fail; goto fail;
dwarf_view_valid = 1; dwarf_view_valid = 1;
for (i = 0; i < (int) DWSECT_MAX; ++i) for (i = 0; i < (int) DEBUG_MAX; ++i)
{ {
if (dwsect[i].offset == 0) if (dwsect[i].offset == 0)
dwsect[i].data = NULL; dwsect[i].data = NULL;
...@@ -1297,27 +1286,28 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset, ...@@ -1297,27 +1286,28 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
+ (dwsect[i].offset - min_offset)); + (dwsect[i].offset - min_offset));
} }
if (!backtrace_dwarf_add (state, 0, dwarf_sections.data[DEBUG_INFO] = dwsect[DEBUG_INFO].data;
dwsect[DWSECT_INFO].data, dwarf_sections.size[DEBUG_INFO] = dwsect[DEBUG_INFO].size;
dwsect[DWSECT_INFO].size,
#if BACKTRACE_XCOFF_SIZE == 32 #if BACKTRACE_XCOFF_SIZE == 32
/* XXX workaround for broken lineoff */ /* XXX workaround for broken lineoff */
dwsect[DWSECT_LINE].data - 4, dwarf_sections.data[DEBUG_LINE] = dwsect[DEBUG_LINE].data - 4;
#else #else
/* XXX workaround for broken lineoff */ /* XXX workaround for broken lineoff */
dwsect[DWSECT_LINE].data - 12, dwarf_sections.data[DEBUG_LINE] = dwsect[DEBUG_LINE].data - 12;
#endif #endif
dwsect[DWSECT_LINE].size, dwarf_sections.size[DEBUG_LINE] = dwsect[DEBUG_LINE].size;
dwsect[DWSECT_ABBREV].data, dwarf_sections.data[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].data;
dwsect[DWSECT_ABBREV].size, dwarf_sections.size[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].size;
dwsect[DWSECT_RANGES].data, dwarf_sections.data[DEBUG_RANGES] = dwsect[DEBUG_RANGES].data;
dwsect[DWSECT_RANGES].size, dwarf_sections.size[DEBUG_RANGES] = dwsect[DEBUG_RANGES].size;
dwsect[DWSECT_STR].data, dwarf_sections.data[DEBUG_STR] = dwsect[DEBUG_STR].data;
dwsect[DWSECT_STR].size, dwarf_sections.size[DEBUG_STR] = dwsect[DEBUG_STR].size;
if (!backtrace_dwarf_add (state, 0, &dwarf_sections,
1, /* big endian */ 1, /* big endian */
NULL, NULL, /* altlink */
error_callback, data, fileline_fn, error_callback, data, fileline_fn,
NULL)) NULL /* returned fileline_entry */))
goto fail; goto fail;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment