* pe-dll.c (build_filler_bfd): Conform error message to standard.
[deliverable/binutils-gdb.git] / bfd / dwarf2.c
index 9f654139d20c9cedb2ddabaf137318d237440437..5cfcc908e8dccb2ff709e52e1c8935fc1f54dca0 100644 (file)
@@ -347,16 +347,35 @@ read_indirect_string (struct comp_unit* unit,
 static bfd_uint64_t
 read_address (struct comp_unit *unit, bfd_byte *buf)
 {
-  switch (unit->addr_size)
+  int signed_vma = get_elf_backend_data (unit->abfd)->sign_extend_vma;
+
+  if (signed_vma)
     {
-    case 8:
-      return bfd_get_64 (unit->abfd, buf);
-    case 4:
-      return bfd_get_32 (unit->abfd, buf);
-    case 2:
-      return bfd_get_16 (unit->abfd, buf);
-    default:
-      abort ();
+      switch (unit->addr_size)
+       {
+       case 8:
+         return bfd_get_signed_64 (unit->abfd, buf);
+       case 4:
+         return bfd_get_signed_32 (unit->abfd, buf);
+       case 2:
+         return bfd_get_signed_16 (unit->abfd, buf);
+       default:
+         abort ();
+       }
+    }
+  else
+    {
+      switch (unit->addr_size)
+       {
+       case 8:
+         return bfd_get_64 (unit->abfd, buf);
+       case 4:
+         return bfd_get_32 (unit->abfd, buf);
+       case 2:
+         return bfd_get_16 (unit->abfd, buf);
+       default:
+         abort ();
+       }
     }
 }
 
@@ -703,7 +722,6 @@ struct funcinfo
   char *file;                          /* Source location file name */
   int line;                            /* Source location line number */
   int tag;
-  int nesting_level;
   char *name;
   struct arange arange;
   asection *sec;                       /* Where the symbol is defined */
@@ -719,6 +737,7 @@ struct varinfo
   int line;
   int tag;
   char *name;
+  bfd_vma addr;
   /* Where the symbol is defined */
   asection *sec;
   /* Is this a stack variable? */
@@ -1411,28 +1430,8 @@ lookup_address_in_function_table (struct comp_unit *unit,
 
   if (best_fit)
     {
-      struct funcinfo* curr_func = best_fit;
-
       *functionname_ptr = best_fit->name;
       *function_ptr = best_fit;
-
-      /* If we found a match and it is a function that was inlined,
-        traverse the function list looking for the function at the
-        next higher scope and save a pointer to it for future use.
-        Note that because of the way the DWARF info is generated, and
-        the way we build the function list, the first function at the
-        next higher level is the one we want. */
-
-      for (each_func = best_fit -> prev_func;
-          each_func && (curr_func->tag == DW_TAG_inlined_subroutine);
-          each_func = each_func->prev_func)
-       {
-         if (each_func->nesting_level < curr_func->nesting_level)
-           {
-             curr_func->caller_func = each_func;
-             curr_func = each_func;
-           }
-       }
       return TRUE;
     }
   else
@@ -1495,6 +1494,7 @@ lookup_symbol_in_function_table (struct comp_unit *unit,
 static bfd_boolean
 lookup_symbol_in_variable_table (struct comp_unit *unit,
                                 asymbol *sym,
+                                bfd_vma addr,
                                 const char **filename_ptr,
                                 unsigned int *linenumber_ptr)
 {
@@ -1504,6 +1504,9 @@ lookup_symbol_in_variable_table (struct comp_unit *unit,
 
   for (each = unit->variable_table; each; each = each->prev_var)
     if (each->stack == 0
+       && each->file != NULL
+       && each->name != NULL
+       && each->addr == addr
        && (!each->sec || each->sec == sec)
        && strcmp (name, each->name) == 0)
       break;
@@ -1544,17 +1547,22 @@ find_abstract_instance_name (struct comp_unit *unit, bfd_uint64_t die_ref)
        }
       else
        {
-         for (i = 0; i < abbrev->num_attrs && !name; ++i)
+         for (i = 0; i < abbrev->num_attrs; ++i)
            {
              info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr);
              switch (attr.name)
                {
                case DW_AT_name:
-                 name = attr.u.str;
+                 /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name.  */
+                 if (name == NULL)
+                   name = attr.u.str;
                  break;
                case DW_AT_specification:
                  name = find_abstract_instance_name (unit, attr.u.val);
                  break;
+               case DW_AT_MIPS_linkage_name:
+                 name = attr.u.str;
+                 break;
                default:
                  break;
                }
@@ -1582,7 +1590,7 @@ read_rangelist (struct comp_unit *unit, struct arange *arange, bfd_uint64_t offs
       bfd_vma low_pc;
       bfd_vma high_pc;
 
-      if (unit->offset_size == 4)
+      if (unit->addr_size == 4)
        {
          low_pc = read_4_bytes (unit->abfd, ranges_ptr);
          ranges_ptr += 4;
@@ -1616,6 +1624,16 @@ scan_unit_for_symbols (struct comp_unit *unit)
   bfd *abfd = unit->abfd;
   bfd_byte *info_ptr = unit->first_child_die_ptr;
   int nesting_level = 1;
+  struct funcinfo **nested_funcs;
+  int nested_funcs_size;
+
+  /* Maintain a stack of in-scope functions and inlined functions, which we
+     can use to set the caller_func field.  */
+  nested_funcs_size = 32;
+  nested_funcs = bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
+  if (nested_funcs == NULL)
+    return FALSE;
+  nested_funcs[nesting_level] = 0;
 
   while (nesting_level)
     {
@@ -1642,6 +1660,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
          (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."),
                             abbrev_number);
          bfd_set_error (bfd_error_bad_value);
+         free (nested_funcs);
          return FALSE;
        }
 
@@ -1653,9 +1672,17 @@ scan_unit_for_symbols (struct comp_unit *unit)
          bfd_size_type amt = sizeof (struct funcinfo);
          func = bfd_zalloc (abfd, amt);
          func->tag = abbrev->tag;
-         func->nesting_level = nesting_level;
          func->prev_func = unit->function_table;
          unit->function_table = func;
+
+         if (func->tag == DW_TAG_inlined_subroutine)
+           for (i = nesting_level - 1; i >= 1; i--)
+             if (nested_funcs[i])
+               {
+                 func->caller_func = nested_funcs[i];
+                 break;
+               }
+         nested_funcs[nesting_level] = func;
        }
       else
        {
@@ -1669,6 +1696,9 @@ scan_unit_for_symbols (struct comp_unit *unit)
              var->prev_var = unit->variable_table;
              unit->variable_table = var;
            }
+
+         /* No inline function in scope at this nesting level.  */
+         nested_funcs[nesting_level] = 0;
        }
 
       for (i = 0; i < abbrev->num_attrs; ++i)
@@ -1749,21 +1779,31 @@ scan_unit_for_symbols (struct comp_unit *unit)
                  break;
 
                case DW_AT_location:
-                 if (var->stack)
+                 switch (attr.form)
                    {
-                     switch (attr.form)
+                   case DW_FORM_block:
+                   case DW_FORM_block1:
+                   case DW_FORM_block2:
+                   case DW_FORM_block4:
+                     if (*attr.u.blk->data == DW_OP_addr)
                        {
-                       case DW_FORM_block:
-                       case DW_FORM_block1:
-                       case DW_FORM_block2:
-                       case DW_FORM_block4:
-                         if (*attr.u.blk->data == DW_OP_addr)
-                           var->stack = 0;
-                         break;
-
-                       default:
-                         break;
+                         var->stack = 0;
+
+                         /* Verify that DW_OP_addr is the only opcode in the
+                            location, in which case the block size will be 1
+                            plus the address size.  */
+                         /* ??? For TLS variables, gcc can emit
+                            DW_OP_addr <addr> DW_OP_GNU_push_tls_address
+                            which we don't handle here yet.  */
+                         if (attr.u.blk->size == unit->addr_size + 1U)
+                           var->addr = bfd_get (unit->addr_size * 8,
+                                                unit->abfd,
+                                                attr.u.blk->data + 1);
                        }
+                     break;
+                   
+                   default:
+                     break;
                    }
                  break;
 
@@ -1779,9 +1819,29 @@ scan_unit_for_symbols (struct comp_unit *unit)
        }
 
       if (abbrev->has_children)
-       nesting_level++;
+       {
+         nesting_level++;
+
+         if (nesting_level >= nested_funcs_size)
+           {
+             struct funcinfo **tmp;
+
+             nested_funcs_size *= 2;
+             tmp = bfd_realloc (nested_funcs,
+                                (nested_funcs_size
+                                 * sizeof (struct funcinfo *)));
+             if (tmp == NULL)
+               {
+                 free (nested_funcs);
+                 return FALSE;
+               }
+             nested_funcs = tmp;
+           }
+         nested_funcs[nesting_level] = 0;
+       }
     }
 
+  free (nested_funcs);
   return TRUE;
 }
 
@@ -2073,7 +2133,8 @@ comp_unit_find_line (struct comp_unit *unit,
                                            filename_ptr,
                                            linenumber_ptr);
   else
-    return lookup_symbol_in_variable_table (unit, sym, filename_ptr,
+    return lookup_symbol_in_variable_table (unit, sym, addr,
+                                           filename_ptr,
                                            linenumber_ptr);
 }
 
@@ -2148,9 +2209,9 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
   stash = *pinfo;
   addr = offset;
   if (section->output_section)
-    addr += section->output_section->vma + section->output_offset;
+    addr += section->output_section->lma + section->output_offset;
   else
-    addr += section->vma;
+    addr += section->lma;
   *filename_ptr = NULL;
   *functionname_ptr = NULL;
   *linenumber_ptr = 0;
@@ -2357,9 +2418,9 @@ _bfd_dwarf2_find_line (bfd *abfd,
 
   addr = symbol->value;
   if (section->output_section)
-    addr += section->output_section->vma + section->output_offset;
+    addr += section->output_section->lma + section->output_offset;
   else
-    addr += section->vma;
+    addr += section->lma;
 
   *filename_ptr = NULL;
   stash = *pinfo;
This page took 0.028229 seconds and 4 git commands to generate.