libbacktrace: simplify DWARF section handling
authorIan Lance Taylor <iant@golang.org>
Thu, 5 Dec 2019 02:20:11 +0000 (02:20 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 5 Dec 2019 02:20:11 +0000 (02:20 +0000)
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

libbacktrace/ChangeLog
libbacktrace/dwarf.c
libbacktrace/elf.c
libbacktrace/internal.h
libbacktrace/pecoff.c
libbacktrace/xcoff.c

index 09ebf5de081593b820dcb35f2cf1f3b578e2ea30..365aef7d4bdb960f13952689fc92f838fd33e511 100644 (file)
@@ -1,3 +1,32 @@
+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>
 
        * configure: Regenerate.
index f338489fe4496fa8c550722936eb0fb49b11bc7b..93d35710561107c3ee81cc1269c9c1c29a76d3fb 100644 (file)
@@ -373,18 +373,8 @@ struct dwarf_data
   struct unit **units;
   /* Number of units in the list.  */
   size_t units_count;
-  /* The unparsed .debug_info section.  */
-  const unsigned char *dwarf_info;
-  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;
+  /* The unparsed DWARF debug data.  */
+  struct dwarf_sections dwarf_sections;
   /* Whether the data is big-endian or not.  */
   int is_bigendian;
   /* 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,
            val->encoding = ATTR_VAL_NONE;
            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");
            return 0;
          }
        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;
       }
     default:
@@ -1499,10 +1490,7 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
 
 static int
 build_address_map (struct backtrace_state *state, uintptr_t base_address,
-                  const unsigned char *dwarf_info, size_t dwarf_info_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,
+                  const struct dwarf_sections *dwarf_sections,
                   int is_bigendian, struct dwarf_data *altlink,
                   backtrace_error_callback error_callback, void *data,
                   struct unit_addrs_vector *addrs,
@@ -1525,9 +1513,9 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
      not sure why.  */
 
   info.name = ".debug_info";
-  info.start = dwarf_info;
-  info.buf = dwarf_info;
-  info.left = dwarf_info_size;
+  info.start = dwarf_sections->data[DEBUG_INFO];
+  info.buf = info.start;
+  info.left = dwarf_sections->size[DEBUG_INFO];
   info.is_bigendian = is_bigendian;
   info.error_callback = error_callback;
   info.data = data;
@@ -1583,7 +1571,9 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
 
       memset (&u->abbrevs, 0, sizeof u->abbrevs);
       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))
        goto fail;
 
@@ -1610,8 +1600,10 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
       u->function_addrs_count = 0;
 
       if (!find_address_ranges (state, base_address, &unit_buf,
-                               dwarf_str, dwarf_str_size,
-                               dwarf_ranges, dwarf_ranges_size,
+                               dwarf_sections->data[DEBUG_STR],
+                               dwarf_sections->size[DEBUG_STR],
+                               dwarf_sections->data[DEBUG_RANGES],
+                               dwarf_sections->size[DEBUG_RANGES],
                                is_bigendian, altlink, error_callback, data,
                                u, addrs, &unit_tag))
        goto fail;
@@ -2089,16 +2081,16 @@ read_line_info (struct backtrace_state *state, struct dwarf_data *ddata,
   memset (hdr, 0, sizeof *hdr);
 
   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);
       goto fail;
     }
 
   line_buf.name = ".debug_line";
-  line_buf.start = ddata->dwarf_line;
-  line_buf.buf = ddata->dwarf_line + u->lineoff;
-  line_buf.left = ddata->dwarf_line_size - u->lineoff;
+  line_buf.start = ddata->dwarf_sections.data[DEBUG_LINE];
+  line_buf.buf = ddata->dwarf_sections.data[DEBUG_LINE] + u->lineoff;
+  line_buf.left = ddata->dwarf_sections.size[DEBUG_LINE] - u->lineoff;
   line_buf.is_bigendian = ddata->is_bigendian;
   line_buf.error_callback = error_callback;
   line_buf.data = data;
@@ -2241,7 +2233,7 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u,
   offset -= u->unit_data_offset;
 
   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.left = u->unit_data_len - offset;
   unit_buf.is_bigendian = ddata->is_bigendian;
@@ -2267,7 +2259,8 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u,
 
       if (!read_attribute (abbrev->attrs[i].form, &unit_buf,
                           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))
        return NULL;
 
@@ -2364,16 +2357,16 @@ add_function_ranges (struct backtrace_state *state, struct dwarf_data *ddata,
 {
   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);
       return 0;
     }
 
   ranges_buf.name = ".debug_ranges";
-  ranges_buf.start = ddata->dwarf_ranges;
-  ranges_buf.buf = ddata->dwarf_ranges + ranges;
-  ranges_buf.left = ddata->dwarf_ranges_size - ranges;
+  ranges_buf.start = ddata->dwarf_sections.data[DEBUG_RANGES];
+  ranges_buf.buf = ddata->dwarf_sections.data[DEBUG_RANGES] + ranges;
+  ranges_buf.left = ddata->dwarf_sections.size[DEBUG_RANGES] - ranges;
   ranges_buf.is_bigendian = ddata->is_bigendian;
   ranges_buf.error_callback = error_callback;
   ranges_buf.data = data;
@@ -2479,7 +2472,8 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
 
          if (!read_attribute (abbrev->attrs[i].form, unit_buf,
                               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))
            return 0;
 
@@ -2698,7 +2692,7 @@ read_function_info (struct backtrace_state *state, struct dwarf_data *ddata,
     }
 
   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.left = u->unit_data_len;
   unit_buf.is_bigendian = ddata->is_bigendian;
@@ -3077,16 +3071,7 @@ dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
 static struct dwarf_data *
 build_dwarf_data (struct backtrace_state *state,
                  uintptr_t base_address,
-                 const unsigned char *dwarf_info,
-                 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,
+                 const struct dwarf_sections *dwarf_sections,
                  int is_bigendian,
                  struct dwarf_data *altlink,
                  backtrace_error_callback error_callback,
@@ -3100,11 +3085,9 @@ build_dwarf_data (struct backtrace_state *state,
   size_t units_count;
   struct dwarf_data *fdata;
 
-  if (!build_address_map (state, base_address, dwarf_info, dwarf_info_size,
-                         dwarf_abbrev, dwarf_abbrev_size, dwarf_ranges,
-                         dwarf_ranges_size, dwarf_str, dwarf_str_size,
-                         is_bigendian, altlink, error_callback, data,
-                         &addrs_vec, &units_vec))
+  if (!build_address_map (state, base_address, dwarf_sections, is_bigendian,
+                         altlink, error_callback, data, &addrs_vec,
+                         &units_vec))
     return NULL;
 
   if (!backtrace_vector_release (state, &addrs_vec.vec, error_callback, data))
@@ -3132,14 +3115,7 @@ build_dwarf_data (struct backtrace_state *state,
   fdata->addrs_count = addrs_count;
   fdata->units = units;
   fdata->units_count = units_count;
-  fdata->dwarf_info = dwarf_info;
-  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->dwarf_sections = *dwarf_sections;
   fdata->is_bigendian = is_bigendian;
   memset (&fdata->fvec, 0, sizeof fdata->fvec);
 
@@ -3153,16 +3129,7 @@ build_dwarf_data (struct backtrace_state *state,
 int
 backtrace_dwarf_add (struct backtrace_state *state,
                     uintptr_t base_address,
-                    const unsigned char *dwarf_info,
-                    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,
+                    const struct dwarf_sections *dwarf_sections,
                     int is_bigendian,
                     struct dwarf_data *fileline_altlink,
                     backtrace_error_callback error_callback,
@@ -3171,10 +3138,7 @@ backtrace_dwarf_add (struct backtrace_state *state,
 {
   struct dwarf_data *fdata;
 
-  fdata = build_dwarf_data (state, base_address, dwarf_info, dwarf_info_size,
-                           dwarf_line, dwarf_line_size, dwarf_abbrev,
-                           dwarf_abbrev_size, dwarf_ranges, dwarf_ranges_size,
-                           dwarf_str, dwarf_str_size, is_bigendian,
+  fdata = build_dwarf_data (state, base_address, dwarf_sections, is_bigendian,
                            fileline_altlink, error_callback, data);
   if (fdata == NULL)
     return 0;
index f3988ec02a05400b5631eea810589035a269a632..89e0ab7169db0d5a185a054f7de7db223c6eed3e 100644 (file)
@@ -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,
index 065b9535e8b0f24bfc584fbb21835fad132e85ba..31004bbd954a1df7b0b69ab018b109b8f2a44790 100644 (file)
@@ -286,22 +286,36 @@ extern int backtrace_initialize (struct backtrace_state *state,
                                 void *data,
                                 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;
 
 /* Add file/line information for a DWARF module.  */
 
 extern int backtrace_dwarf_add (struct backtrace_state *state,
                                uintptr_t base_address,
-                               const unsigned char* dwarf_info,
-                               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,
+                               const struct dwarf_sections *dwarf_sections,
                                int is_bigendian,
                                struct dwarf_data *fileline_altlink,
                                backtrace_error_callback error_callback,
index fcf9508d488ce59a44ae7e3e700265fa90cd6d1f..fe64a7e695bcb4f524d9f2203dcdb588107c95f7 100644 (file)
@@ -133,19 +133,7 @@ typedef struct {
   uint16_t sc;
 } b_coff_internal_symbol;
 
-/* An index of sections we care about.  */
-
-enum debug_section
-{
-  DEBUG_INFO,
-  DEBUG_LINE,
-  DEBUG_ABBREV,
-  DEBUG_RANGES,
-  DEBUG_STR,
-  DEBUG_MAX
-};
-
-/* Names of sections, indexed by enum debug_section.  */
+/* Names of sections, indexed by enum dwarf_section in internal.h.  */
 
 static const char * const debug_section_names[DEBUG_MAX] =
 {
@@ -164,8 +152,6 @@ struct debug_section_info
   off_t offset;
   /* Section size.  */
   size_t size;
-  /* Section contents, after read from file.  */
-  const unsigned char *data;
 };
 
 /* Information we keep for an coff symbol.  */
@@ -616,6 +602,7 @@ coff_add (struct backtrace_state *state, int descriptor,
   struct backtrace_view debug_view;
   int debug_view_valid;
   uintptr_t image_base;
+  struct dwarf_sections dwarf_sections;
 
   *found_sym = 0;
   *found_dwarf = 0;
@@ -848,28 +835,20 @@ coff_add (struct backtrace_state *state, int descriptor,
 
   for (i = 0; i < (int) DEBUG_MAX; ++i)
     {
-      if (sections[i].size == 0)
-       sections[i].data = NULL;
+      size_t size = sections[i].size;
+      dwarf_sections.size[i] = size;
+      if (size == 0)
+       dwarf_sections.data[i] = NULL;
       else
-       sections[i].data = ((const unsigned char *) debug_view.data
-                           + (sections[i].offset - min_offset));
+       dwarf_sections.data[i] = ((const unsigned char *) debug_view.data
+                                 + (sections[i].offset - min_offset));
     }
 
-  if (!backtrace_dwarf_add (state, /* base_address */ 0,
-                           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,
-                           0, /* FIXME */
-                           NULL,
+  if (!backtrace_dwarf_add (state, /* base_address */ 0, &dwarf_sections,
+                           0, /* FIXME: is_bigendian */
+                           NULL, /* altlink */
                            error_callback, data, fileline_fn,
-                           NULL))
+                           NULL /* returned fileline_entry */))
     goto fail;
 
   *found_dwarf = 1;
index bc60962fe041086fcab150164ce85ee2f4daf106..468b24c418d7cfd98ae37ba9b0dfd309e5ea7c05 100644 (file)
@@ -387,18 +387,6 @@ struct xcoff_fileline_data
   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.  */
 
 struct dwsect_info
@@ -1100,7 +1088,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
   off_t str_off;
   off_t min_offset;
   off_t max_offset;
-  struct dwsect_info dwsect[DWSECT_MAX];
+  struct dwsect_info dwsect[DEBUG_MAX];
   size_t sects_size;
   size_t syms_size;
   int32_t str_size;
@@ -1111,6 +1099,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
   int dwarf_view_valid;
   int magic_ok;
   int i;
+  struct dwarf_sections dwarf_sections;
 
   *found_sym = 0;
 
@@ -1255,19 +1244,19 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
       switch (sects[i].s_flags & 0xffff0000)
        {
          case SSUBTYP_DWINFO:
-           idx = DWSECT_INFO;
+           idx = DEBUG_INFO;
            break;
          case SSUBTYP_DWLINE:
-           idx = DWSECT_LINE;
+           idx = DEBUG_LINE;
            break;
          case SSUBTYP_DWABREV:
-           idx = DWSECT_ABBREV;
+           idx = DEBUG_ABBREV;
            break;
          case SSUBTYP_DWARNGE:
-           idx = DWSECT_RANGES;
+           idx = DEBUG_RANGES;
            break;
          case SSUBTYP_DWSTR:
-           idx = DWSECT_STR;
+           idx = DEBUG_STR;
            break;
          default:
            continue;
@@ -1288,7 +1277,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
        goto fail;
       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)
            dwsect[i].data = NULL;
@@ -1297,27 +1286,28 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
                              + (dwsect[i].offset - min_offset));
        }
 
-      if (!backtrace_dwarf_add (state, 0,
-                               dwsect[DWSECT_INFO].data,
-                               dwsect[DWSECT_INFO].size,
+      dwarf_sections.data[DEBUG_INFO] = dwsect[DEBUG_INFO].data;
+      dwarf_sections.size[DEBUG_INFO] = dwsect[DEBUG_INFO].size;
 #if BACKTRACE_XCOFF_SIZE == 32
-                               /* XXX workaround for broken lineoff */
-                               dwsect[DWSECT_LINE].data - 4,
+      /* XXX workaround for broken lineoff */
+      dwarf_sections.data[DEBUG_LINE] = dwsect[DEBUG_LINE].data - 4;
 #else
-                               /* XXX workaround for broken lineoff */
-                               dwsect[DWSECT_LINE].data - 12,
+      /* XXX workaround for broken lineoff */
+      dwarf_sections.data[DEBUG_LINE] = dwsect[DEBUG_LINE].data - 12;
 #endif
-                               dwsect[DWSECT_LINE].size,
-                               dwsect[DWSECT_ABBREV].data,
-                               dwsect[DWSECT_ABBREV].size,
-                               dwsect[DWSECT_RANGES].data,
-                               dwsect[DWSECT_RANGES].size,
-                               dwsect[DWSECT_STR].data,
-                               dwsect[DWSECT_STR].size,
+      dwarf_sections.size[DEBUG_LINE] = dwsect[DEBUG_LINE].size;
+      dwarf_sections.data[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].data;
+      dwarf_sections.size[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].size;
+      dwarf_sections.data[DEBUG_RANGES] = dwsect[DEBUG_RANGES].data;
+      dwarf_sections.size[DEBUG_RANGES] = dwsect[DEBUG_RANGES].size;
+      dwarf_sections.data[DEBUG_STR] = dwsect[DEBUG_STR].data;
+      dwarf_sections.size[DEBUG_STR] = dwsect[DEBUG_STR].size;
+
+      if (!backtrace_dwarf_add (state, 0, &dwarf_sections,
                                1, /* big endian */
-                               NULL,
+                               NULL, /* altlink */
                                error_callback, data, fileline_fn,
-                               NULL))
+                               NULL /* returned fileline_entry */))
        goto fail;
     }