This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][newbie] Make gdb accept -feliminate-dwarf2-dups stuff


Hello, everyone:

Current CVS gcc has an option "-feliminate-dwarf2-dups" that
generates dwarf2 debug info containing references across compilation
units, which current gdb seems to be unable to parse.  I wrote a
quick-and-dirty patch (against 20040103 snapshot) to make it work.

The patch isn't really clean (in particular it contains a known memory
leak as indicated by the FIXME), and I don't really expect it to be
included.  However, I think this patch *might* be useful to someone,
since "-feliminate-dwarf2-dups" seems to reduce debug info size
significantly for large projects (the effect is more clear when the
DW* symbols for DWARF-2 relocation are deleted), which may be helpful
to distributors making debug-info packages.  Maybe some of you may
tell me some way to improve the patch, as well as to make it
accessible to those needing similar functionality.

Hopefully you'll CC me since I'm not subscribed.

--- dwarf2read.c	2004/01/09 16:38:02	1.1
+++ dwarf2read.c	2004/01/10 14:14:22
@@ -50,6 +50,9 @@
 #include "gdb_assert.h"
 #include <sys/types.h>
 
+#include <search.h>
+#include <stdlib.h>
+
 #ifndef DWARF2_REG_TO_REGNUM
 #define DWARF2_REG_TO_REGNUM(REG) (REG)
 #endif
@@ -173,6 +176,19 @@
 #define ABBREV_HASH_SIZE 121
 #endif
 
+struct cu_list
+{
+  unsigned ncu;
+  struct cu_list_entry *cus;
+};
+
+struct cu_list_entry
+{
+  unsigned offset, length;
+  struct partial_symtab *pst;
+  void *deps; /* direct dependencies; organized in a tree as in tsearch() */
+};
+
 /* The data in a compilation unit header, after target2host
    translation, looks like this.  */
 struct comp_unit_head
@@ -333,6 +349,7 @@
     struct die_info *parent;	/* Its parent, if any.  */
 
     struct type *type;		/* Cached type information */
+    unsigned cu_idx;
   };
 
 /* Attributes have a name and a value */
@@ -506,6 +523,9 @@
     /* Size of dwarf locations buffer for the objfile.  */
 
     unsigned int dwarf_loc_size;
+
+    struct cu_list *cu_list;
+    unsigned cu_entry_idx;
   };
 
 #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
@@ -523,6 +543,8 @@
 #define DWARF_RANGES_SIZE(p)    (PST_PRIVATE(p)->dwarf_ranges_size)
 #define DWARF_LOC_BUFFER(p)     (PST_PRIVATE(p)->dwarf_loc_buffer)
 #define DWARF_LOC_SIZE(p)       (PST_PRIVATE(p)->dwarf_loc_size)
+#define CU_LIST(p) (PST_PRIVATE(p)->cu_list)
+#define CU_ENTRY_IDX(p) (PST_PRIVATE(p)->cu_entry_idx)
 
 /* Maintain an array of referenced fundamental types for the current
    compilation unit being read.  For DWARF version 1, we have to construct
@@ -739,6 +761,7 @@
 static void set_cu_language (unsigned int);
 
 static struct attribute *dwarf_attr (struct die_info *, unsigned int);
+static struct attribute *dwarf_attr0 (struct die_info *die, unsigned int name, unsigned *pcu_idx);
 
 static int die_is_declaration (struct die_info *);
 
@@ -885,6 +908,8 @@
 
 static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
 
+static unsigned int dwarf2_get_ref_die_offset_for_cu (struct attribute *attr, unsigned cu_idx);
+     
 static struct die_info *follow_die_ref (unsigned int);
 
 static struct type *dwarf2_fundamental_type (struct objfile *, int);
@@ -912,6 +937,12 @@
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 			     struct dwarf2_cu *cu);
 
+static int cu_dep_compare(const void *pa, const void *pb);
+
+static void cu_dep_destroy(void *p);
+
+static char *add_die_deps (bfd *abfd, char *info_ptr, struct dwarf2_cu *cu);
+
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.  */
 
@@ -1128,6 +1159,9 @@
 /* Build the partial symbol table by doing a quick pass through the
    .debug_info and .debug_abbrev sections.  */
 
+static struct cu_list *cur_cu_list;
+static struct cu_list_entry *cur_cu_entry;
+
 static void
 dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
 {
@@ -1141,6 +1175,12 @@
   struct cleanup *back_to;
   CORE_ADDR lowpc, highpc;
 
+  static struct cu_list_entry *cus = NULL;
+  static unsigned cus_size = 0;
+  unsigned ncu, i;
+  struct cu_list_entry *cus_priv;
+  struct cu_list *cu_list_priv;
+
   info_ptr = dwarf_info_buffer;
   abbrev_ptr = dwarf_abbrev_buffer;
 
@@ -1175,6 +1215,42 @@
   obstack_init (&dwarf2_tmp_obstack);
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
 
+  /* FIXME: should use obstack growth functions */
+  ncu = 0;
+  while (info_ptr < dwarf_info_buffer + dwarf_info_size)
+    {
+      struct dwarf2_cu cu;
+      beg_of_comp_unit = info_ptr;
+
+      cu.objfile = objfile;
+      info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd);
+
+      if (ncu >= cus_size) {
+	if (cus_size == 0) {
+	  cus_size = 4;
+	  cus = (struct cu_list_entry *) xmalloc(cus_size * sizeof(struct cu_list_entry));
+	} else {
+	  cus_size = ncu * 2;
+	  cus = (struct cu_list_entry *) xrealloc(cus, cus_size * sizeof(struct cu_list_entry));
+	}
+      }
+      cus[ncu].offset = beg_of_comp_unit - dwarf_info_buffer;
+      cus[ncu].length = cu.header.length + cu.header.initial_length_size;
+      cus[ncu].pst = NULL;
+      cus[ncu].deps = NULL; /* FIXME: free deps after use */
+      ncu++;
+
+      info_ptr = beg_of_comp_unit + cu.header.length 
+                                  + cu.header.initial_length_size;
+    }
+  info_ptr = dwarf_info_buffer;
+  cus_priv = obstack_alloc (&objfile->psymbol_obstack, ncu * sizeof (struct cu_list_entry));
+  memcpy(cus_priv, cus, ncu * sizeof (struct cu_list_entry));
+  cu_list_priv = obstack_alloc (&objfile->psymbol_obstack, sizeof (struct cu_list));
+  cu_list_priv->ncu = ncu;
+  cu_list_priv->cus = cus_priv;
+  cur_cu_list = cu_list_priv;
+
   /* Since the objects we're extracting from dwarf_info_buffer vary in
      length, only the individual functions to extract them (like
      read_comp_unit_head and read_partial_die) can really know whether
@@ -1188,11 +1264,13 @@
 
      For this loop condition, simply checking whether there's any data
      left at all should be sufficient.  */
+  i = 0;
   while (info_ptr < dwarf_info_buffer + dwarf_info_size)
     {
       struct dwarf2_cu cu;
       beg_of_comp_unit = info_ptr;
 
+      cur_cu_entry = &cus_priv[i];
       cu.objfile = objfile;
       info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd);
 
@@ -1263,6 +1341,10 @@
       /* Store the function that reads in the rest of the symbol table */
       pst->read_symtab = dwarf2_psymtab_to_symtab;
 
+      CU_LIST (pst) = cu_list_priv;
+      CU_ENTRY_IDX (pst) = i;
+      cus_priv[i].pst = pst;
+      
       /* Check if comp unit has_children.
          If so, read the rest of the partial symbols from this comp unit.
          If not, there's no more debug_info for this comp unit. */
@@ -1296,6 +1378,11 @@
 	(objfile->static_psymbols.list + pst->statics_offset);
       sort_pst_symbols (pst);
 
+      /* Build dependency table */
+      info_ptr = cu.header.first_die_ptr;
+      while (info_ptr < beg_of_comp_unit + cu.header.length + cu.header.initial_length_size)
+	info_ptr = add_die_deps(abfd, info_ptr, &cu);
+      
       /* If there is already a psymtab or symtab for a file of this
          name, remove it. (If there is a symtab, more drastic things
          also happen.) This happens in VxWorks.  */
@@ -1303,7 +1390,12 @@
 
       info_ptr = beg_of_comp_unit + cu.header.length 
                                   + cu.header.initial_length_size;
+      i++;
     }
+  
+  gdb_assert(i == ncu);
+  cur_cu_list = NULL;
+  cur_cu_entry = NULL;
   do_cleanups (back_to);
 }
 
@@ -1653,7 +1745,9 @@
     {
       if (pst->readin)
 	{
+#if 0
 	  warning ("bug: psymtab for %s is already read in.", pst->filename);
+#endif
 	}
       else
 	{
@@ -1672,12 +1766,65 @@
     }
 }
 
+static unsigned *dep_list = NULL, dep_list_size = 0;
+static unsigned dep_list_len = 0;
+static void *all_deps;
+
+static void
+dep_list_add (unsigned idx)
+{
+  if (dep_list_len >= dep_list_size) {
+    if (dep_list_size == 0) {
+      dep_list_size = 4;
+      dep_list = (unsigned *) xmalloc (dep_list_size * sizeof(unsigned));
+    } else {
+      dep_list_size = dep_list_len * 2;
+      dep_list = (unsigned *) xrealloc (dep_list, dep_list_size * sizeof(unsigned));
+    }
+  }
+  dep_list[dep_list_len] = idx;
+  dep_list_len++;
+}
+
+static void
+process_dep (unsigned idx);
+
+static void
+process_subdeps (const void *p, VISIT visit, int level)
+{
+  unsigned idx = (unsigned) * (const void *const *) p;
+
+  process_dep(idx);
+}
+
+static void
+process_dep (unsigned idx)
+{
+  struct cu_list_entry *cu_entry;
+  void *cur_deps;
+
+  /* Already processed?  Or being processed at a parent level due to a circular reference? */
+  if (! tfind ((const void *) idx, &all_deps, cu_dep_compare)) {
+    if (info_verbose) printf_filtered ("* Start processing %u.\n", idx);
+    tsearch ((const void *) idx, &all_deps, cu_dep_compare);
+    cu_entry = &cur_cu_list->cus[idx];
+    cur_deps = cu_entry->deps;
+    /* Process them if they have not been processed */
+    twalk (cur_deps, process_subdeps);
+    dep_list_add (idx);
+    if (info_verbose) printf_filtered ("* Done processing %u.\n", idx);
+  }
+}
+
+static unsigned cur_cu_idx = ~0UL;
+
 static void
 psymtab_to_symtab_1 (struct partial_symtab *pst)
 {
   struct objfile *objfile = pst->objfile;
   bfd *abfd = objfile->obfd;
   struct dwarf2_cu cu;
+  struct die_info **die_lists;
   struct die_info *dies;
   unsigned long offset;
   CORE_ADDR lowpc, highpc;
@@ -1687,6 +1834,33 @@
   struct cleanup *back_to;
   struct attribute *attr;
 
+  unsigned i, idx;
+
+  obstack_init (&dwarf2_tmp_obstack);
+  back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
+
+  cur_cu_list = CU_LIST (pst);
+  idx = CU_ENTRY_IDX (pst);
+
+  all_deps = NULL;
+  dep_list_len = 0;
+  process_dep (idx);
+  tdestroy (all_deps, cu_dep_destroy);
+
+  buildsym_init ();
+  make_cleanup (really_free_pendings, NULL);
+
+  dwarf2_empty_hash_tables ();
+  
+  die_lists = obstack_alloc (&dwarf2_tmp_obstack, dep_list_len * sizeof (struct die_info *));
+
+  /* Pass 1: build the reference table */
+  for (i = 0; i < dep_list_len; i++) {
+    idx = dep_list[i];
+    cur_cu_idx = idx;
+    pst = cur_cu_list->cus[idx].pst;
+
+    if (info_verbose) printf_filtered ("* Start building reference table for %u.\n", idx);
   /* Set local variables from the partial symbol table info.  */
   offset = DWARF_INFO_OFFSET (pst);
   dwarf_info_buffer = DWARF_INFO_BUFFER (pst);
@@ -1706,11 +1881,49 @@
   cu_header_offset = offset;
   info_ptr = dwarf_info_buffer + offset;
 
-  obstack_init (&dwarf2_tmp_obstack);
-  back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
+    cu.objfile = objfile;
 
-  buildsym_init ();
-  make_cleanup (really_free_pendings, NULL);
+    /* read in the comp_unit header  */
+    info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd);
+
+    /* Read the abbrevs for this compilation unit  */
+    dwarf2_read_abbrevs (abfd, &cu);
+    make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs);
+
+    die_lists[i] = read_comp_unit (info_ptr, abfd, &cu);
+
+    make_cleanup_free_die_list (die_lists[i]);
+
+    if (info_verbose) printf_filtered ("* Done building reference table for %u.\n", idx);
+  }
+
+  /* Pass 2: do the actual work */
+  for (i = 0; i < dep_list_len; i++) {
+    idx = dep_list[i];
+    cur_cu_idx = idx; /* should be unnecessary */
+    pst = cur_cu_list->cus[idx].pst;
+    if (pst->readin) continue;
+
+    if (info_verbose) printf_filtered ("* Start loading %u.\n", idx);
+    /* Set local variables from the partial symbol table info.  */
+    offset = DWARF_INFO_OFFSET (pst);
+    dwarf_info_buffer = DWARF_INFO_BUFFER (pst);
+    dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER (pst);
+    dwarf_abbrev_size = DWARF_ABBREV_SIZE (pst);
+    dwarf_line_buffer = DWARF_LINE_BUFFER (pst);
+    dwarf_line_size = DWARF_LINE_SIZE (pst);
+    dwarf_str_buffer = DWARF_STR_BUFFER (pst);
+    dwarf_str_size = DWARF_STR_SIZE (pst);
+    dwarf_macinfo_buffer = DWARF_MACINFO_BUFFER (pst);
+    dwarf_macinfo_size = DWARF_MACINFO_SIZE (pst);
+    dwarf_ranges_buffer = DWARF_RANGES_BUFFER (pst);
+    dwarf_ranges_size = DWARF_RANGES_SIZE (pst);
+    dwarf_loc_buffer = DWARF_LOC_BUFFER (pst);
+    dwarf_loc_size = DWARF_LOC_SIZE (pst);
+    baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
+
+    cu_header_offset = offset;
+    info_ptr = dwarf_info_buffer + offset;
 
   cu.objfile = objfile;
 
@@ -1721,9 +1934,7 @@
   dwarf2_read_abbrevs (abfd, &cu);
   make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs);
 
-  dies = read_comp_unit (info_ptr, abfd, &cu);
-
-  make_cleanup_free_die_list (dies);
+    dies = die_lists[i];
 
   /* Find the base address of the compilation unit for range lists and
      location lists.  It will normally be specified by DW_AT_low_pc.
@@ -1789,6 +2000,10 @@
     }
   pst->symtab = symtab;
   pst->readin = 1;
+    if (info_verbose) printf_filtered ("* Done loading %u.\n", idx);
+  }
+  cur_cu_idx = ~0UL;
+  cur_cu_list = NULL;
 
   do_cleanups (back_to);
 }
@@ -3686,8 +3901,6 @@
 {
   /* Reset die reference table; we are
      building new ones now.  */
-  dwarf2_empty_hash_tables ();
-
   return read_die_and_children (info_ptr, abfd, cu, &info_ptr, NULL);
 }
 
@@ -3954,6 +4167,99 @@
 
 /* Read a minimal amount of information into the minimal die structure.  */
 
+static int
+cu_list_compare(const void *pa, const void *pb)
+{
+  const struct cu_list_entry
+    *a = (const struct cu_list_entry *) pa,
+    *b = (const struct cu_list_entry *) pb;
+  if (a->offset >= b->offset && a->offset < (b->offset + b->length)) return 0;
+  else if (b->offset >= a->offset && b->offset < (a->offset + a->length)) return 0;
+  else if (a->offset < b->offset) return -1;
+  else return 1;
+}
+
+static int
+cu_dep_compare(const void *pa, const void *pb)
+{
+  unsigned a = (unsigned) pa, b = (unsigned) pb;
+  return (a > b) - (a < b);
+}
+
+static void
+cu_dep_destroy(void *p)
+{
+}
+
+static void
+add_dep(struct attribute *attr)
+{
+  struct cu_list_entry tmp, *ent;
+  unsigned idx;
+  
+  tmp.offset = dwarf2_get_ref_die_offset(attr);
+  tmp.length = 0;
+  if (cu_list_compare(&tmp, cur_cu_entry) == 0) return; /* We don't need self-dependencies */
+  ent = bsearch(&tmp, cur_cu_list->cus, cur_cu_list->ncu, sizeof(struct cu_list_entry), cu_list_compare);
+  if (ent == NULL)
+    error("Dwarf Error: Invalid referent offset %u.", tmp.offset);
+  else {
+    gdb_assert(ent != cur_cu_entry);
+    idx = ent - cur_cu_list->cus;
+    /* Adds the element if it does not already exist */
+    if (! tfind ((const void *) idx, &cur_cu_entry->deps, cu_dep_compare)) {
+      tsearch ((const void *) idx, &cur_cu_entry->deps, cu_dep_compare);
+      if (info_verbose)
+	printf_filtered ("* Added dependency %u for %u (ref offset <%x>).\n",
+			 idx, cur_cu_entry - cur_cu_list->cus, tmp.offset);
+    }
+  }
+}
+
+static char *
+add_die_deps (bfd *abfd, char *info_ptr, struct dwarf2_cu *cu)
+{
+  unsigned int abbrev_number, bytes_read, i;
+  struct abbrev_info *abbrev;
+  struct attribute attr;
+  struct attribute spec_attr;
+  int found_spec_attr = 0;
+  int has_low_pc_attr = 0;
+  int has_high_pc_attr = 0;
+
+  abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+  info_ptr += bytes_read;
+  if (!abbrev_number)
+    return info_ptr;
+
+  abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
+  if (!abbrev)
+    {
+      error ("Dwarf Error: Could not find abbrev number %d [in module %s]", abbrev_number,
+		      bfd_get_filename (abfd));
+    }
+
+  for (i = 0; i < abbrev->num_attrs; ++i)
+    {
+      info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, info_ptr, cu);
+
+      /* Store the data if it is of an attribute we want to keep in a
+         partial symbol table.  */
+      switch (attr.name)
+	{
+	case DW_AT_type:
+	case DW_AT_containing_type:
+	case DW_AT_abstract_origin:
+	case DW_AT_specification:
+	case DW_AT_extension:
+	  add_dep(&attr);
+	  break;
+	}
+    }
+
+  return info_ptr;
+}
+
 static char *
 read_partial_die (struct partial_die_info *part_die, bfd *abfd,
 		  char *info_ptr, struct dwarf2_cu *cu)
@@ -4041,6 +4347,8 @@
 	  found_spec_attr = 1;
 	  spec_attr = attr;
 	  break;
+	case DW_AT_extension:
+	  break;
 	case DW_AT_sibling:
 	  /* Ignore absolute siblings, they might point outside of
 	     the current compile unit.  */
@@ -4632,14 +4940,18 @@
   cu_language_defn = language_def (cu_language);
 }
 
-/* Return the named attribute or NULL if not there.  */
+/* Return the named attribute or NULL if not there.
+   If pcu_idx is not NULL, it is set to the compilation unit index corresponding
+   to the die containing the actual attribute definition (i.e., after redirections
+   by DW_AT_spec). */
 
 static struct attribute *
-dwarf_attr (struct die_info *die, unsigned int name)
+dwarf_attr0 (struct die_info *die, unsigned int name, unsigned *pcu_idx)
 {
   unsigned int i;
   struct attribute *spec = NULL;
 
+  if (pcu_idx) *pcu_idx = die->cu_idx; /* not the final value */
   for (i = 0; i < die->num_attrs; ++i)
     {
       if (die->attrs[i].name == name)
@@ -4653,15 +4965,21 @@
   if (spec)
     {
       struct die_info *ref_die =
-      follow_die_ref (dwarf2_get_ref_die_offset (spec));
+      follow_die_ref (dwarf2_get_ref_die_offset_for_cu (spec, die->cu_idx));
 
       if (ref_die)
-	return dwarf_attr (ref_die, name);
+	return dwarf_attr0 (ref_die, name, pcu_idx);
     }
 
   return NULL;
 }
 
+static struct attribute *
+dwarf_attr (struct die_info *die, unsigned int name)
+{
+  return dwarf_attr0(die, name, NULL);
+}
+
 static int
 die_is_declaration (struct die_info *die)
 {
@@ -5475,8 +5793,9 @@
   struct attribute *type_attr;
   struct die_info *type_die;
   unsigned int ref;
+  unsigned cu_idx;
 
-  type_attr = dwarf_attr (die, DW_AT_type);
+  type_attr = dwarf_attr0 (die, DW_AT_type, &cu_idx);
   if (!type_attr)
     {
       /* A missing DW_AT_type represents a void type.  */
@@ -5484,7 +5803,7 @@
     }
   else
     {
-      ref = dwarf2_get_ref_die_offset (type_attr);
+      ref = dwarf2_get_ref_die_offset_for_cu (type_attr, cu_idx);
       type_die = follow_die_ref (ref);
       if (!type_die)
 	{
@@ -5513,11 +5832,12 @@
   struct attribute *type_attr;
   struct die_info *type_die = NULL;
   unsigned int ref;
+  unsigned cu_idx;
 
-  type_attr = dwarf_attr (die, DW_AT_containing_type);
+  type_attr = dwarf_attr0 (die, DW_AT_containing_type, &cu_idx);
   if (type_attr)
     {
-      ref = dwarf2_get_ref_die_offset (type_attr);
+      ref = dwarf2_get_ref_die_offset_for_cu (type_attr, cu_idx);
       type_die = follow_die_ref (ref);
       if (!type_die)
 	{
@@ -5783,12 +6103,13 @@
   struct attribute *attr;
   struct die_info *extension_die;
   unsigned int ref;
+  unsigned cu_idx;
 
-  attr = dwarf_attr (die, DW_AT_extension);
+  attr = dwarf_attr0 (die, DW_AT_extension, &cu_idx);
   if (attr == NULL)
     return NULL;
 
-  ref = dwarf2_get_ref_die_offset (attr);
+  ref = dwarf2_get_ref_die_offset_for_cu (attr, cu_idx);
   extension_die = follow_die_ref (ref);
   if (!extension_die)
     {
@@ -6701,7 +7022,7 @@
 }
 
 static unsigned int
-dwarf2_get_ref_die_offset (struct attribute *attr)
+dwarf2_get_ref_die_offset0 (struct attribute *attr, unsigned base)
 {
   unsigned int result = 0;
 
@@ -6715,7 +7036,7 @@
     case DW_FORM_ref4:
     case DW_FORM_ref8:
     case DW_FORM_ref_udata:
-      result = cu_header_offset + DW_UNSND (attr);
+      result = base + DW_UNSND (attr);
       break;
     default:
       complaint (&symfile_complaints,
@@ -6725,6 +7046,22 @@
   return result;
 }
 
+/* can only be used when one compilation unit is processed at a time
+   (so it cannot be used when actually loading the symbols) */
+static unsigned int
+dwarf2_get_ref_die_offset (struct attribute *attr)
+{
+  return dwarf2_get_ref_die_offset0 (attr, cu_header_offset);
+}
+
+/* can only be used when cur_cu_list is defined (for example, when actually loading
+   the symbols) */
+static unsigned int
+dwarf2_get_ref_die_offset_for_cu (struct attribute *attr, unsigned cu_idx)
+{
+  return dwarf2_get_ref_die_offset0 (attr, cur_cu_list->cus[cu_idx].offset);
+}
+
 static struct die_info *
 follow_die_ref (unsigned int offset)
 {
@@ -7026,6 +7363,7 @@
 
   die = (struct die_info *) xmalloc (sizeof (struct die_info));
   memset (die, 0, sizeof (struct die_info));
+  die->cu_idx = cur_cu_idx;
   return (die);
 }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]