gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / dwarf2.c
index 61c459ea9f853e2515e01bfe55d9389020c087ba..9ed4a4a2871f03bc88c3c132a25453fe8423ba79 100644 (file)
@@ -1,5 +1,5 @@
 /* DWARF 2 support.
-   Copyright (C) 1994-2019 Free Software Foundation, Inc.
+   Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
    Adapted from gdb/dwarf2read.c by Gavin Koch of Cygnus Solutions
    (gavin@cygnus.com).
@@ -135,6 +135,12 @@ struct dwarf2_debug_file
 
   /* Last comp unit in list above.  */
   struct comp_unit *last_comp_unit;
+
+  /* Line table at line_offset zero.  */
+  struct line_info_table *line_table;
+
+  /* Hash table to map offsets to decoded abbrevs.  */
+  htab_t abbrev_offsets;
 };
 
 struct dwarf2_debug
@@ -289,12 +295,12 @@ struct comp_unit
 /* This data structure holds the information of an abbrev.  */
 struct abbrev_info
 {
-  unsigned int number;         /* Number identifying abbrev.  */
-  enum dwarf_tag tag;          /* DWARF tag.  */
-  int has_children;            /* Boolean.  */
-  unsigned int num_attrs;      /* Number of attributes.  */
-  struct attr_abbrev *attrs;   /* An array of attribute descriptions.  */
-  struct abbrev_info *next;    /* Next in chain.  */
+  unsigned int         number;         /* Number identifying abbrev.  */
+  enum dwarf_tag       tag;            /* DWARF tag.  */
+  bfd_boolean          has_children;   /* TRUE if the abbrev has children.  */
+  unsigned int         num_attrs;      /* Number of attributes.  */
+  struct attr_abbrev * attrs;          /* An array of attribute descriptions.  */
+  struct abbrev_info * next;           /* Next in chain.  */
 };
 
 struct attr_abbrev
@@ -929,6 +935,51 @@ lookup_abbrev (unsigned int number, struct abbrev_info **abbrevs)
   return NULL;
 }
 
+/* We keep a hash table to map .debug_abbrev section offsets to the
+   array of abbrevs, so that compilation units using the same set of
+   abbrevs do not waste memory.  */
+
+struct abbrev_offset_entry
+{
+  size_t offset;
+  struct abbrev_info **abbrevs;
+};
+
+static hashval_t
+hash_abbrev (const void *p)
+{
+  const struct abbrev_offset_entry *ent = p;
+  return htab_hash_pointer ((void *) ent->offset);
+}
+
+static int
+eq_abbrev (const void *pa, const void *pb)
+{
+  const struct abbrev_offset_entry *a = pa;
+  const struct abbrev_offset_entry *b = pb;
+  return a->offset == b->offset;
+}
+
+static void
+del_abbrev (void *p)
+{
+  struct abbrev_offset_entry *ent = p;
+  struct abbrev_info **abbrevs = ent->abbrevs;
+  size_t i;
+
+  for (i = 0; i < ABBREV_HASH_SIZE; i++)
+    {
+      struct abbrev_info *abbrev = abbrevs[i];
+
+      while (abbrev)
+       {
+         free (abbrev->attrs);
+         abbrev = abbrev->next;
+       }
+    }
+  free (ent);
+}
+
 /* In DWARF version 2, the description of the debugging information is
    stored in a separate .debug_abbrev section.  Before we read any
    dies from a section we read in all abbreviations and install them
@@ -944,7 +995,18 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash,
   struct abbrev_info *cur_abbrev;
   unsigned int abbrev_number, bytes_read, abbrev_name;
   unsigned int abbrev_form, hash_number;
-  bfd_size_type amt;
+  size_t amt;
+  void **slot;
+  struct abbrev_offset_entry ent = { offset, NULL };
+
+  if (ent.offset != offset)
+    return NULL;
+
+  slot = htab_find_slot (file->abbrev_offsets, &ent, INSERT);
+  if (slot == NULL)
+    return NULL;
+  if (*slot != NULL)
+    return ((struct abbrev_offset_entry *) (*slot))->abbrevs;
 
   if (! read_section (abfd, &stash->debug_sections[debug_abbrev],
                      file->syms, offset,
@@ -1044,6 +1106,12 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash,
       if (lookup_abbrev (abbrev_number, abbrevs) != NULL)
        break;
     }
+
+  *slot = bfd_malloc (sizeof ent);
+  if (!*slot)
+    goto fail;
+  ent.abbrevs = abbrevs;
+  memcpy (*slot, &ent, sizeof ent);
   return abbrevs;
 
  fail:
@@ -1090,7 +1158,7 @@ read_attribute_value (struct attribute *  attr,
   bfd *abfd = unit->abfd;
   unsigned int bytes_read;
   struct dwarf_block *blk;
-  bfd_size_type amt;
+  size_t amt;
 
   if (info_ptr >= info_ptr_end && form != DW_FORM_flag_present)
     {
@@ -1404,19 +1472,24 @@ struct lookup_funcinfo
 
 struct varinfo
 {
-  /* Pointer to previous variable in list of all variables */
+  /* Pointer to previous variable in list of all variables */
   struct varinfo *prev_var;
-  /* Source location file name */
+  /* The offset of the varinfo from the start of the unit.  */
+  bfd_uint64_t unit_offset;
+  /* Source location file name.  */
   char *file;
-  /* Source location line number */
+  /* Source location line number */
   int line;
+  /* The type of this variable.  */
   int tag;
+  /* The name of the variable, if it has one.  */
   char *name;
+  /* The address of the variable.  */
   bfd_vma addr;
-  /* Where the symbol is defined */
+  /* Where the symbol is defined */
   asection *sec;
-  /* Is this a stack variable? */
-  unsigned int stack: 1;
+  /* Is this a stack variable?  */
+  bfd_boolean stack;
 };
 
 /* Return TRUE if NEW_LINE should sort after LINE.  */
@@ -1445,7 +1518,7 @@ add_line_info (struct line_info_table *table,
               unsigned int discriminator,
               int end_sequence)
 {
-  bfd_size_type amt = sizeof (struct line_info);
+  size_t amt = sizeof (struct line_info);
   struct line_sequence* seq = table->sequences;
   struct line_info* info = (struct line_info *) bfd_alloc (table->abfd, amt);
 
@@ -1714,11 +1787,11 @@ static bfd_boolean
 build_line_info_table (struct line_info_table *  table,
                       struct line_sequence *    seq)
 {
-  bfd_size_type      amt;
-  struct line_info** line_info_lookup;
-  struct line_info*  each_line;
-  unsigned int       num_lines;
-  unsigned int       line_index;
+  size_t amt;
+  struct line_info **line_info_lookup;
+  struct line_info *each_line;
+  unsigned int num_lines;
+  unsigned int line_index;
 
   if (seq->line_info_lookup != NULL)
     return TRUE;
@@ -1756,12 +1829,12 @@ build_line_info_table (struct line_info_table *  table,
 static bfd_boolean
 sort_line_sequences (struct line_info_table* table)
 {
-  bfd_size_type                 amt;
-  struct line_sequence*         sequences;
-  struct line_sequence*         seq;
-  unsigned int          n = 0;
-  unsigned int          num_sequences = table->num_sequences;
-  bfd_vma               last_high_pc;
+  size_t amt;
+  struct line_sequence *sequences;
+  struct line_sequence *seq;
+  unsigned int n = 0;
+  unsigned int num_sequences = table->num_sequences;
+  bfd_vma last_high_pc;
 
   if (num_sequences == 0)
     return TRUE;
@@ -1829,7 +1902,7 @@ line_info_add_include_dir (struct line_info_table *table, char *cur_dir)
   if ((table->num_dirs % DIR_ALLOC_CHUNK) == 0)
     {
       char **tmp;
-      bfd_size_type amt;
+      size_t amt;
 
       amt = table->num_dirs + DIR_ALLOC_CHUNK;
       amt *= sizeof (char *);
@@ -1863,7 +1936,7 @@ line_info_add_file_name (struct line_info_table *table, char *cur_file,
   if ((table->num_files % FILE_ALLOC_CHUNK) == 0)
     {
       struct fileinfo *tmp;
-      bfd_size_type amt;
+      size_t amt;
 
       amt = table->num_files + FILE_ALLOC_CHUNK;
       amt *= sizeof (struct fileinfo);
@@ -2023,31 +2096,16 @@ decode_line_info (struct comp_unit *unit)
   char *cur_file, *cur_dir;
   unsigned char op_code, extended_op, adj_opcode;
   unsigned int exop_len;
-  bfd_size_type amt;
+  size_t amt;
+
+  if (unit->line_offset == 0 && file->line_table)
+    return file->line_table;
 
   if (! read_section (abfd, &stash->debug_sections[debug_line],
                      file->syms, unit->line_offset,
                      &file->dwarf_line_buffer, &file->dwarf_line_size))
     return NULL;
 
-  amt = sizeof (struct line_info_table);
-  table = (struct line_info_table *) bfd_alloc (abfd, amt);
-  if (table == NULL)
-    return NULL;
-  table->abfd = abfd;
-  table->comp_dir = unit->comp_dir;
-
-  table->num_files = 0;
-  table->files = NULL;
-
-  table->num_dirs = 0;
-  table->dirs = NULL;
-
-  table->num_sequences = 0;
-  table->sequences = NULL;
-
-  table->lcl_head = NULL;
-
   if (file->dwarf_line_size < 16)
     {
       _bfd_error_handler
@@ -2184,6 +2242,24 @@ decode_line_info (struct comp_unit *unit)
       line_ptr += 1;
     }
 
+  amt = sizeof (struct line_info_table);
+  table = (struct line_info_table *) bfd_alloc (abfd, amt);
+  if (table == NULL)
+    return NULL;
+  table->abfd = abfd;
+  table->comp_dir = unit->comp_dir;
+
+  table->num_files = 0;
+  table->files = NULL;
+
+  table->num_dirs = 0;
+  table->dirs = NULL;
+
+  table->num_sequences = 0;
+  table->sequences = NULL;
+
+  table->lcl_head = NULL;
+
   if (lh.version >= 5)
     {
       /* Read directory table.  */
@@ -2344,8 +2420,7 @@ decode_line_info (struct comp_unit *unit)
                    (_("DWARF error: mangled line number section"));
                  bfd_set_error (bfd_error_bad_value);
                line_fail:
-                 if (filename != NULL)
-                   free (filename);
+                 free (filename);
                  goto fail;
                }
              break;
@@ -2390,8 +2465,7 @@ decode_line_info (struct comp_unit *unit)
                filenum = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
                                                 FALSE, line_end);
                line_ptr += bytes_read;
-               if (filename)
-                 free (filename);
+               free (filename);
                filename = concat_filename (table, filenum);
                break;
              }
@@ -2437,10 +2511,11 @@ decode_line_info (struct comp_unit *unit)
            }
        }
 
-      if (filename)
-       free (filename);
+      free (filename);
     }
 
+  if (unit->line_offset == 0)
+    file->line_table = table;
   if (sort_line_sequences (table))
     return table;
 
@@ -2451,10 +2526,8 @@ decode_line_info (struct comp_unit *unit)
       table->sequences = table->sequences->prev_sequence;
       free (seq);
     }
-  if (table->files != NULL)
-    free (table->files);
-  if (table->dirs != NULL)
-    free (table->dirs);
+  free (table->files);
+  free (table->dirs);
   return NULL;
 }
 
@@ -2526,7 +2599,7 @@ lookup_address_in_line_info_table (struct line_info_table *table,
       return seq->last_line->address - seq->low_pc;
     }
 
-fail:
+ fail:
   *filename_ptr = NULL;
   return 0;
 }
@@ -2785,7 +2858,7 @@ lookup_symbol_in_variable_table (struct comp_unit *unit,
   struct varinfo* each;
 
   for (each = unit->variable_table; each; each = each->prev_var)
-    if (each->stack == 0
+    if (! each->stack
        && each->file != NULL
        && each->name != NULL
        && each->addr == addr
@@ -2818,7 +2891,7 @@ find_abstract_instance (struct comp_unit *unit,
                        int *linenumber_ptr)
 {
   bfd *abfd = unit->abfd;
-  bfd_byte *info_ptr;
+  bfd_byte *info_ptr = NULL;
   bfd_byte *info_ptr_end;
   unsigned int abbrev_number, bytes_read, i;
   struct abbrev_info *abbrev;
@@ -2868,14 +2941,38 @@ find_abstract_instance (struct comp_unit *unit,
          return FALSE;
        }
       info_ptr += die_ref;
+    }
+  else if (attr_ptr->form == DW_FORM_GNU_ref_alt)
+    {
+      bfd_boolean first_time = unit->stash->alt.dwarf_info_buffer == NULL;
 
+      info_ptr = read_alt_indirect_ref (unit, die_ref);
+      if (first_time)
+       unit->stash->alt.info_ptr = unit->stash->alt.dwarf_info_buffer;
+      if (info_ptr == NULL)
+       {
+         _bfd_error_handler
+           (_("DWARF error: unable to read alt ref %" PRIu64),
+            (uint64_t) die_ref);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+      info_ptr_end = (unit->stash->alt.dwarf_info_buffer
+                     + unit->stash->alt.dwarf_info_size);
+      if (unit->stash->alt.all_comp_units)
+       unit = unit->stash->alt.all_comp_units;
+    }
+
+  if (attr_ptr->form == DW_FORM_ref_addr
+      || attr_ptr->form == DW_FORM_GNU_ref_alt)
+    {
       /* Now find the CU containing this pointer.  */
       if (info_ptr >= unit->info_ptr_unit && info_ptr < unit->end_ptr)
        info_ptr_end = unit->end_ptr;
       else
        {
          /* Check other CUs to see if they contain the abbrev.  */
-         struct comp_unit * u;
+         struct comp_unit *u;
 
          for (u = unit->prev_unit; u != NULL; u = u->prev_unit)
            if (info_ptr >= u->info_ptr_unit && info_ptr < u->end_ptr)
@@ -2886,15 +2983,27 @@ find_abstract_instance (struct comp_unit *unit,
              if (info_ptr >= u->info_ptr_unit && info_ptr < u->end_ptr)
                break;
 
-         while (u == NULL)
-           {
-             u = stash_comp_unit (unit->stash, unit->file);
-             if (u == NULL)
-               break;
-             if (info_ptr >= u->info_ptr_unit && info_ptr < u->end_ptr)
-               break;
-             u = NULL;
-           }
+         if (attr_ptr->form == DW_FORM_ref_addr)
+           while (u == NULL)
+             {
+               u = stash_comp_unit (unit->stash, &unit->stash->f);
+               if (u == NULL)
+                 break;
+               if (info_ptr >= u->info_ptr_unit && info_ptr < u->end_ptr)
+                 break;
+               u = NULL;
+             }
+
+         if (attr_ptr->form == DW_FORM_GNU_ref_alt)
+           while (u == NULL)
+             {
+               u = stash_comp_unit (unit->stash, &unit->stash->alt);
+               if (u == NULL)
+                 break;
+               if (info_ptr >= u->info_ptr_unit && info_ptr < u->end_ptr)
+                 break;
+               u = NULL;
+             }
 
          if (u == NULL)
            {
@@ -2908,23 +3017,6 @@ find_abstract_instance (struct comp_unit *unit,
          info_ptr_end = unit->end_ptr;
        }
     }
-  else if (attr_ptr->form == DW_FORM_GNU_ref_alt)
-    {
-      info_ptr = read_alt_indirect_ref (unit, die_ref);
-      if (info_ptr == NULL)
-       {
-         _bfd_error_handler
-           (_("DWARF error: unable to read alt ref %" PRIu64),
-            (uint64_t) die_ref);
-         bfd_set_error (bfd_error_bad_value);
-         return FALSE;
-       }
-      info_ptr_end = (unit->stash->alt.dwarf_info_buffer
-                     + unit->stash->alt.dwarf_info_size);
-
-      /* FIXME: Do we need to locate the correct CU, in a similar
-        fashion to the code in the DW_FORM_ref_addr case above ?  */
-    }
   else
     {
       /* DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref8 or
@@ -3061,6 +3153,20 @@ read_rangelist (struct comp_unit *unit, struct arange *arange,
   return TRUE;
 }
 
+static struct varinfo *
+lookup_var_by_offset (bfd_uint64_t offset, struct varinfo * table)
+{
+  while (table)
+    {
+      if (table->unit_offset == offset)
+       return table;
+      table = table->prev_var;
+    }
+
+  return NULL;
+}
+
+
 /* DWARF2 Compilation unit functions.  */
 
 /* Scan over each die in a comp. unit looking for functions to add
@@ -3097,11 +3203,13 @@ scan_unit_for_symbols (struct comp_unit *unit)
       bfd_vma low_pc = 0;
       bfd_vma high_pc = 0;
       bfd_boolean high_pc_relative = FALSE;
+      bfd_uint64_t current_offset;
 
       /* PR 17512: file: 9f405d9d.  */
       if (info_ptr >= info_ptr_end)
        goto fail;
 
+      current_offset = info_ptr - unit->info_ptr_unit;
       abbrev_number = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
                                             FALSE, info_ptr_end);
       info_ptr += bytes_read;
@@ -3129,12 +3237,13 @@ scan_unit_for_symbols (struct comp_unit *unit)
          goto fail;
        }
 
-      var = NULL;
       if (abbrev->tag == DW_TAG_subprogram
          || abbrev->tag == DW_TAG_entry_point
          || abbrev->tag == DW_TAG_inlined_subroutine)
        {
-         bfd_size_type amt = sizeof (struct funcinfo);
+         size_t amt = sizeof (struct funcinfo);
+
+         var = NULL;
          func = (struct funcinfo *) bfd_zalloc (abfd, amt);
          if (func == NULL)
            goto fail;
@@ -3158,17 +3267,20 @@ scan_unit_for_symbols (struct comp_unit *unit)
          func = NULL;
          if (abbrev->tag == DW_TAG_variable)
            {
-             bfd_size_type amt = sizeof (struct varinfo);
+             size_t amt = sizeof (struct varinfo);
              var = (struct varinfo *) bfd_zalloc (abfd, amt);
              if (var == NULL)
                goto fail;
              var->tag = abbrev->tag;
-             var->stack = 1;
+             var->stack = TRUE;
              var->prev_var = unit->variable_table;
              unit->variable_table = var;
+             var->unit_offset = current_offset;
              /* PR 18205: Missing debug information can cause this
                 var to be attached to an already cached unit.  */
            }
+         else
+           var = NULL;
 
          /* No inline function in scope at this nesting level.  */
          nested_funcs[nesting_level].func = 0;
@@ -3257,6 +3369,33 @@ scan_unit_for_symbols (struct comp_unit *unit)
            {
              switch (attr.name)
                {
+               case DW_AT_specification:
+                 if (attr.u.val)
+                   {
+                     struct varinfo * spec_var;
+
+                     spec_var = lookup_var_by_offset (attr.u.val,
+                                                      unit->variable_table);
+                     if (spec_var == NULL)
+                       {       
+                         _bfd_error_handler (_("DWARF error: could not find "
+                                               "variable specification "
+                                               "at offset %lx"),
+                                             (unsigned long) attr.u.val);
+                         break;
+                       }
+
+                     if (var->name == NULL)
+                       var->name = spec_var->name;
+                     if (var->file == NULL && spec_var->file != NULL)
+                       var->file = strdup (spec_var->file);
+                     if (var->line == 0)
+                       var->line = spec_var->line;
+                     if (var->sec == NULL)
+                       var->sec = spec_var->sec;
+                   }
+                 break;
+
                case DW_AT_name:
                  if (is_str_attr (attr.form))
                    var->name = attr.u.str;
@@ -3273,7 +3412,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
 
                case DW_AT_external:
                  if (attr.u.val != 0)
-                   var->stack = 0;
+                   var->stack = FALSE;
                  break;
 
                case DW_AT_location:
@@ -3287,7 +3426,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
                      if (attr.u.blk->data != NULL
                          && *attr.u.blk->data == DW_OP_addr)
                        {
-                         var->stack = 0;
+                         var->stack = FALSE;
 
                          /* Verify that DW_OP_addr is the only opcode in the
                             location, in which case the block size will be 1
@@ -3377,7 +3516,7 @@ parse_comp_unit (struct dwarf2_debug *stash,
   struct abbrev_info *abbrev;
   struct attribute attr;
   bfd_byte *end_ptr = info_ptr + unit_length;
-  bfd_size_type amt;
+  size_t amt;
   bfd_vma low_pc = 0;
   bfd_vma high_pc = 0;
   bfd *abfd = file->bfd_ptr;
@@ -3783,7 +3922,7 @@ comp_unit_hash_info (struct dwarf2_debug *stash,
        each_var = each_var->prev_var)
     {
       /* Skip stack vars and vars with no files or names.  */
-      if (each_var->stack == 0
+      if (! each_var->stack
          && each_var->file != NULL
          && each_var->name != NULL)
        /* There is no need to copy name string into hash table as
@@ -3992,7 +4131,7 @@ place_sections (bfd *orig_bfd, struct dwarf2_debug *stash)
   else
     {
       bfd_vma last_vma = 0, last_dwarf = 0;
-      bfd_size_type amt = i * sizeof (struct adjusted_section);
+      size_t amt = i * sizeof (struct adjusted_section);
 
       p = (struct adjusted_section *) bfd_malloc (amt);
       if (p == NULL)
@@ -4360,7 +4499,7 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
                              void **pinfo,
                              bfd_boolean do_place)
 {
-  bfd_size_type amt = sizeof (struct dwarf2_debug);
+  size_t amt = sizeof (struct dwarf2_debug);
   bfd_size_type total_size;
   asection *msec;
   struct dwarf2_debug *stash = (struct dwarf2_debug *) *pinfo;
@@ -4396,6 +4535,16 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
   if (!save_section_vma (abfd, stash))
     return FALSE;
 
+  stash->f.abbrev_offsets = htab_create_alloc (10, hash_abbrev, eq_abbrev,
+                                              del_abbrev, calloc, free);
+  if (!stash->f.abbrev_offsets)
+    return FALSE;
+
+  stash->alt.abbrev_offsets = htab_create_alloc (10, hash_abbrev, eq_abbrev,
+                                                del_abbrev, calloc, free);
+  if (!stash->alt.abbrev_offsets)
+    return FALSE;
+
   *pinfo = stash;
 
   if (debug_bfd == NULL)
@@ -4983,60 +5132,42 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
     {
       for (each = file->all_comp_units; each; each = each->next_unit)
        {
-         struct abbrev_info **abbrevs = each->abbrevs;
          struct funcinfo *function_table = each->function_table;
          struct varinfo *variable_table = each->variable_table;
-         size_t i;
-
-         for (i = 0; i < ABBREV_HASH_SIZE; i++)
-           {
-             struct abbrev_info *abbrev = abbrevs[i];
 
-             while (abbrev)
-               {
-                 free (abbrev->attrs);
-                 abbrev = abbrev->next;
-               }
-           }
-
-         if (each->line_table)
+         if (each->line_table && each->line_table != file->line_table)
            {
              free (each->line_table->files);
              free (each->line_table->dirs);
            }
 
-         if (each->lookup_funcinfo_table)
-           {
-             free (each->lookup_funcinfo_table);
-             each->lookup_funcinfo_table = NULL;
-           }
+         free (each->lookup_funcinfo_table);
+         each->lookup_funcinfo_table = NULL;
 
          while (function_table)
            {
-             if (function_table->file)
-               {
-                 free (function_table->file);
-                 function_table->file = NULL;
-               }
-             if (function_table->caller_file)
-               {
-                 free (function_table->caller_file);
-                 function_table->caller_file = NULL;
-               }
+             free (function_table->file);
+             function_table->file = NULL;
+             free (function_table->caller_file);
+             function_table->caller_file = NULL;
              function_table = function_table->prev_func;
            }
 
          while (variable_table)
            {
-             if (variable_table->file)
-               {
-                 free (variable_table->file);
-                 variable_table->file = NULL;
-               }
+             free (variable_table->file);
+             variable_table->file = NULL;
              variable_table = variable_table->prev_var;
            }
        }
 
+      if (file->line_table)
+       {
+         free (file->line_table->files);
+         free (file->line_table->dirs);
+       }
+      htab_delete (file->abbrev_offsets);
+
       free (file->dwarf_line_str_buffer);
       free (file->dwarf_str_buffer);
       free (file->dwarf_ranges_buffer);
This page took 0.033729 seconds and 4 git commands to generate.