]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gprofng: fix 32892 source line level information not available with "-g -O2"
authorVladimir Mezentsev <vladimir.mezentsev@oracle.com>
Mon, 19 May 2025 20:13:46 +0000 (13:13 -0700)
committerVladimir Mezentsev <vladimir.mezentsev@oracle.com>
Thu, 22 May 2025 05:50:53 +0000 (22:50 -0700)
gprofng did not read the .debug_rnglists section for dwarf-5.
Another problem was that gprofng ignored DW_AT_abstract_origin
As a result, gprofng skiped Dwarf for all functions declared as:
   <1><e18b>: Abbrev Number: 43 (DW_TAG_subprogram)
      <e18c>   DW_AT_abstract_origin: <0xe168>
      <e190>   DW_AT_linkage_name:  _ZN10Bool_ArrayD2Ev

gprofng/ChangeLog
2025-05-19  Vladimir Mezentsev  <vladimir.mezentsev@oracle.com>

PR 32892
* src/Dwarf.cc: Read the .debug_rnglists section.
Support DW_AT_abstract_origin.
* src/Dwarf.h: Likewise.
* src/DwarfLib.cc: Likewise.
* src/DwarfLib.h: Likewise.
* src/LoadObject.cc (dump_functions): Print mangled names for aliases.
* src/Stabs.cc (fixSymtabAlias): Set 'alias' correctly.
* src/Symbol.cc (find_symbols): Add argument where to collect symbols.
* src/Symbol.h: Likewise.

gprofng/src/Dwarf.cc
gprofng/src/Dwarf.h
gprofng/src/DwarfLib.cc
gprofng/src/DwarfLib.h
gprofng/src/LoadObject.cc
gprofng/src/Stabs.cc
gprofng/src/Symbol.cc
gprofng/src/Symbol.h

index 23ac5b9e55da6fca3b264c650a58cd810d24fd89..858910992e743b36d6592708e39f7baa6aa805ef 100644 (file)
@@ -390,6 +390,7 @@ Dwarf::Dwarf (Stabs *_stabs)
   debug_lineSec = dwrGetSec (NTXT (".debug_line"));
   debug_rangesSec = dwrGetSec (NTXT (".debug_ranges"));
   debug_line_strSec = dwrGetSec (".debug_line_str");
+  debug_rnglists = NULL;
 
   if ((debug_infoSec == NULL) || (debug_abbrevSec == NULL) || (debug_lineSec == NULL))
     {
@@ -496,9 +497,24 @@ DwrCU::parseChild (Dwarf_cnt *ctx)
          break;
        case DW_TAG_subprogram:
        {
-         if (dwrTag.get_attr (DW_AT_abstract_origin))
-           break;
          Symbol *sym = NULL;
+         Vector<Symbol *> *syms = NULL;
+         Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_abstract_origin);
+         if (dwrAttr)
+           {
+             // Set up functions from DW_AT_{ranges,low_pc,linkage_name}
+             set_up_funcs (dwrAttr->u.offset);
+             break;
+           }
+
+         dwrAttr = dwrTag.get_attr (DW_AT_specification);
+         if (dwrAttr)
+           {
+             // Set up functions from DW_AT_{ranges,low_pc,linkage_name}
+             set_up_funcs (dwrAttr->u.offset);
+             break;
+           }
+
          if (dwrTag.get_attr (DW_AT_declaration))
            {
              // Only declaration
@@ -508,58 +524,26 @@ DwrCU::parseChild (Dwarf_cnt *ctx)
                  if (link_name && streq (link_name, NTXT ("MAIN")))
                    ctx->fortranMAIN = Stabs::find_func (NTXT ("MAIN"),
                                            ctx->module->functions, true, true);
-                 }
-               sym = Symbol::get_symbol (symbols_sorted_by_name,
-                                        get_linkage_name ());
-               if (sym == NULL)
-                 break;
+               }
+             sym = Symbol::get_symbol (symbols_sorted_by_name,
+                                      get_linkage_name ());
+             if (sym != NULL)
                func = append_Function (sym, ctx->name);
-               break;
+             break;
            }
 
-         Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_specification);
-         if (dwrAttr)
+         func = NULL;
+         syms = get_symbols (tmp_syms);
+         for (int i = 0, sz = VecSize (syms); i < sz; i++)
            {
-             // Find previous declaration to inherit settings.
-             sym = find_declaration (dwrAttr->u.offset);
-             if (sym == NULL)
-               break;
-             func = sym->func;
-             if (func == NULL)
-               break;
-             set_source (func);
-
-             Vector <Range *> *ranges = get_ranges ();
-             if (ranges)
-               {
-                 Vector<Symbol *> *syms = Symbol::find_symbols (symbols, ranges);
-                 Destroy (ranges);
-                 for (int i = 0, sz = VecSize (syms); i < sz; i++)
-                   {
-                     Symbol *sp = syms->get (i);
-                     if (sp->alias)
-                       sp = sp->alias;
-                     Function *f = sp->func;
-                     if (f == NULL)
-                       f = sp->createFunction (func->module);
-                     f->setLineFirst (func->line_first);
-                     f->setDefSrc (func->def_source);
-                   }
-                 delete (syms);
-               }
-             break;
+             sym = syms->get (i);
+             func = append_Function (sym, ctx->name);
+             if (Stabs::is_fortran (ctx->module->lang_code) &&
+             streq (func->get_match_name (), "MAIN"))
+               ctx->fortranMAIN = func;
            }
-
-         sym = Symbol::get_symbol (symbols_sorted_by_name, get_linkage_name ());
-         if (sym == NULL)
-           sym = Symbol::get_symbol (symbols, get_low_pc ());
-         if (sym == NULL)
+         if (func == NULL)
            break;
-         func = append_Function (sym, ctx->name);
-         if (Stabs::is_fortran (ctx->module->lang_code) &&
-             streq (func->get_match_name (), "MAIN"))
-           ctx->fortranMAIN = func;
-         set_source (func);
 
          old_name = ctx->name;
          Function *old_func = ctx->func;
@@ -712,14 +696,6 @@ Dwarf::srcline_Dwarf (Module *module)
   dwrCU->map_dwarf_lines (module);
 }
 
-static int
-rangeCmp (const void *a, const void *b)
-{
-  Range *item1 = *((Range **) a);
-  Range *item2 = *((Range **) b);
-  return item1->low < item2->low ? -1 : (item1->low == item2->low ? 0 : 1);
-}
-
 Vector<Range *> *
 Dwarf::get_ranges (uint64_t offset)
 {
@@ -741,7 +717,6 @@ Dwarf::get_ranges (uint64_t offset)
        break;
       ranges->append (new Range (low_pc, high_pc));
     }
-  ranges->sort (rangeCmp);
   return ranges;
 }
 
@@ -1127,3 +1102,94 @@ DwrCU::Dwarf_lang ()
       return Sp_lang_unknown;
     }
 }
+
+Vector <Dwr_rng_entry *> *
+Dwarf::get_debug_rnglists ()
+{
+  if (debug_rnglists != NULL)
+    return debug_rnglists;
+  debug_rnglists = new Vector <Dwr_rng_entry *> ();
+
+  DwrSec *debug_rnglistsSec = dwrGetSec (".debug_rnglists");
+  if (debug_rnglistsSec == NULL)
+    {
+      Dprintf (1, "No section .debug_rnglists\n");
+      return debug_rnglists;
+    }
+  while (debug_rnglistsSec->offset < debug_rnglistsSec->sizeSec)
+    {
+      uint64_t base_address = 0;
+      uint64_t length = debug_rnglistsSec->ReadLength ();
+      Dwr_rng_entry *rng = new Dwr_rng_entry ();
+      debug_rnglists->append (rng);
+      rng->offset = debug_rnglistsSec->offset;
+      rng->length = length;
+      rng->fmt64 = debug_rnglistsSec->fmt64;
+      rng->version = debug_rnglistsSec->Get_16 ();
+      rng->address_size = debug_rnglistsSec->Get_8 ();
+      rng->segment_selector_size = debug_rnglistsSec->Get_8 ();
+      rng->offset_entry_count = debug_rnglistsSec->Get_32 ();
+      while (debug_rnglistsSec->offset < debug_rnglistsSec->size)
+       {
+         uint64_t off = debug_rnglistsSec->offset;
+         uint64_t low_pc;
+         uint64_t high_pc;
+         int re = debug_rnglistsSec->Get_8 ();
+         switch (re)
+           {
+           case DW_RLE_end_of_list:
+             low_pc = 0;
+             high_pc = 0;
+             break;
+           case DW_RLE_base_address:
+             base_address = debug_rnglistsSec->GetADDR ();
+             low_pc = base_address;
+             high_pc = 0;
+             continue;
+           case DW_RLE_start_length:
+             low_pc = debug_rnglistsSec->GetADDR ();
+             high_pc = low_pc + debug_rnglistsSec->GetULEB128 ();
+             break;
+           case DW_RLE_offset_pair:
+             low_pc = base_address + debug_rnglistsSec->GetULEB128 ();
+             high_pc = base_address + debug_rnglistsSec->GetULEB128 ();
+             break;
+           case DW_RLE_start_end:
+             low_pc = debug_rnglistsSec->GetADDR ();
+             high_pc = debug_rnglistsSec->GetADDR ();
+             break;
+           case DW_RLE_base_addressx:
+             base_address = debug_rnglistsSec->GetULEB128 ();
+             low_pc = base_address;
+             high_pc = 0;
+             continue;
+
+             // TODO x-variants need .debug_addr support used for split-dwarf
+           case DW_RLE_startx_endx:
+             low_pc = debug_rnglistsSec->GetRef ();
+             high_pc = debug_rnglistsSec->GetRef ();
+             Dprintf (1, "DW_RLE_startx_endx is not implemented\n");
+             continue;
+           case DW_RLE_startx_length:
+             low_pc = debug_rnglistsSec->GetRef ();
+             high_pc = low_pc + debug_rnglistsSec->GetULEB128 ();
+             Dprintf (1, "DW_RLE_startx_length is not implemented\n");
+             continue;
+           default:
+             Dprintf (1, "Unknown tag DW_RLE: %d, offset=0x%llx\n", re,
+                      (long long) off);
+             debug_rnglistsSec->offset = debug_rnglistsSec->size;
+             continue;
+           }
+         Dprintf (DUMP_DWARFLIB, "0x%08llx %d-%-20s [0x%08llx - 0x%08llx)\n",
+                  (long long) off, re, Dwr_rng_entry::rng_entry2str (re),
+                  (long long) low_pc, (long long) high_pc);
+         rng->ranges->append (new ExtRange (off, low_pc, high_pc));
+       }
+      debug_rnglistsSec->size = debug_rnglistsSec->sizeSec;
+      debug_rnglistsSec->offset = length;
+    }
+  delete debug_rnglistsSec;
+  debug_rnglists->dump ("Dwarf::get_debug_rnglists");
+  return debug_rnglists;
+}
index f46ad3fcf98aeb2237f859c801f9aa459a5aa597..bf8ffb43ddc91532790c3f3f38a40ad825e71ee3 100644 (file)
@@ -71,6 +71,7 @@ public:
   void srcline_Dwarf (Module *module);
   void read_hwcprof_info (Module *module);
   Vector<Range *> *get_ranges (uint64_t offset);
+  Vector <Dwr_rng_entry *> *get_debug_rnglists ();
 
   Stabs::Stab_status status;
   Vector<DwrCU *> *dwrCUs;
@@ -84,6 +85,7 @@ public:
   Stabs *stabs;
 
 private:
+  Vector <Dwr_rng_entry *> *debug_rnglists;
   DwrSec *dwrGetSec (const char *sec_name);
 };
 
index 9f55ab34ab0c9bd328b96c9fedec3737c9e9149f..79be8cf58c5b86ce75dd648179b23e73776da673 100644 (file)
@@ -998,7 +998,6 @@ Dwr_Tag::dump ()
        case DW_FORM_strx2:
        case DW_FORM_strx3:
        case DW_FORM_strx4:
-       case DW_FORM_implicit_const:
          Dprintf (DUMP_DWARFLIB, "  \"%s\"", atrp->u.str ? atrp->u.str : "<NULL>");
          break;
        case DW_FORM_block:
@@ -1037,6 +1036,7 @@ Dwr_Tag::dump ()
        case DW_FORM_exprloc:
        case DW_FORM_ref_sig8:
        case DW_FORM_flag_present:
+       case DW_FORM_implicit_const:
          Dprintf (DUMP_DWARFLIB, "  0x%llx (%lld)", (long long) atrp->u.val,
                   (long long) atrp->u.val);
          break;
@@ -1095,6 +1095,7 @@ DwrSec::bounds_violation (uint64_t sz)
     {
       Dprintf (DEBUG_ERR_MSG, "DwrSec::bounds_violation: offset=%lld + sz=%lld > size=%lld\n",
               (long long) offset, (long long) sz, (long long) size);
+      offset = size;
       return true;
     }
   return false;
@@ -1795,6 +1796,10 @@ DwrLineRegs::getPath (int fn)
 DwrCU::DwrCU (Dwarf *_dwarf)
 {
   dwarf = _dwarf;
+  tmp_syms = new Vector<Symbol*>();
+  rng_list = NULL;
+  rng_list_inited = false;
+  base_address = 0;
   symbols = NULL;
   symbols_sorted_by_name = NULL;
   cu_offset = dwarf->debug_infoSec->offset;
@@ -1887,6 +1892,7 @@ DwrCU::~DwrCU ()
   delete dwrLineReg;
   delete symbols;
   delete symbols_sorted_by_name;
+  delete tmp_syms;
   free (comp_dir);
 }
 
@@ -1929,7 +1935,7 @@ DwrCU::build_abbrevTable (DwrSec *_debug_abbrevSec, uint64_t _offset)
          switch (atf.at_form)
            {
            case DW_FORM_implicit_const:
-             atf.len = debug_abbrevSec->GetSLEB128 ();
+             atf.u.val = debug_abbrevSec->GetSLEB128 ();
              break;
            }
          abbrevAtForm->append (atf);
@@ -2113,7 +2119,7 @@ DwrCU::set_die (Dwarf_Die die)
          atf->len = 0;
          break;
        case DW_FORM_implicit_const:
-         atf->u.str = NULL;
+         // atf->u.val is already set
          break;
        default:
          DEBUG_CODE
@@ -2193,17 +2199,46 @@ DwrCU::parse_cu_header (LoadObject *lo)
   module->set_name (path);
 
   // create a list of functions in this CU
+  base_address = get_low_pc ();
   Vector <Range *> *ranges = get_ranges ();
   if (ranges)
     {
       Vector <Symbol *> *syms = dwarf->stabs->get_symbols ();
-      symbols = Symbol::find_symbols (syms, ranges);
-      symbols_sorted_by_name = Symbol::sort_by_name (syms);
+      symbols = Symbol::find_symbols (syms, ranges, new Vector <Symbol *> ());
+      symbols_sorted_by_name = Symbol::sort_by_name (symbols);
+      if (DUMP_ELF_SYM)
+       symbols->dump ("DwrCU::parse_cu_header: symbols");
       Destroy (ranges);
     }
   return module;
 }
 
+
+static int
+cmp_ExtRange (const void *a, const void *b)
+{
+  uint64_t a1 = *((uint64_t *) a);
+  ExtRange *rng = *((ExtRange **) b);
+  uint64_t b1 = rng->offset;
+  return a1 < b1 ? -1 : (a1 == b1 ? 0 : 1);
+}
+
+static int
+cmp_offset (const void *a, const void *b)
+{
+  uint64_t off = *((uint64_t *) a);
+  Dwr_rng_entry *rng = *((Dwr_rng_entry **) b);
+  return off < rng->offset ? -1 : (off < rng->length ? 0 : 1);
+}
+
+static int
+rangeCmp (const void *a, const void *b)
+{
+  Range *item1 = *((Range **) a);
+  Range *item2 = *((Range **) b);
+  return item1->low < item2->low ? -1 : (item1->low == item2->low ? 0 : 1);
+}
+
 Vector <Range *> *
 DwrCU::get_ranges ()
 {
@@ -2211,9 +2246,48 @@ DwrCU::get_ranges ()
   Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_ranges);
   if (dwrAttr)
     {
-      Dprintf (DUMP_DWARFLIB, "DwrCU::get_ranges: 0x%llx\n",
-              (long long) dwrAttr->u.offset);
-      ranges = dwarf->get_ranges (dwrAttr->u.offset);
+      uint64_t offset = dwrAttr->u.offset;
+      Dprintf (DUMP_DWARFLIB, "DwrCU::get_ranges: 0x%llx\n", (long long) offset);
+      if (version < 5)
+       ranges = dwarf->get_ranges (offset);
+      else
+       {
+         if (rng_list == NULL && !rng_list_inited)
+           {
+             rng_list_inited = true;
+             // Find the corresponding section in .debug_rnglists
+             Vector <Dwr_rng_entry *> *rng_entrys = dwarf->get_debug_rnglists ();
+             if (rng_entrys == NULL)
+               return NULL;
+             int ind = rng_entrys->bisearch (0, -1, &offset, cmp_offset);
+             if (ind != -1)
+               rng_list = rng_entrys->get (ind);
+             else
+               {
+                 Dprintf (1, "Cannot find rnglist. DW_AT_ranges=0x%llx\n",
+                          (long long) offset);
+                 return NULL;
+               }
+           }
+         if (rng_list == NULL)
+           return NULL;
+         int ind = rng_list->ranges->bisearch (0, -1, &offset, cmp_ExtRange);
+         if (ind == -1)
+           {
+             Dprintf (1, "Cannot find rnglist. DW_AT_ranges=0x%llx\n",
+                      (long long) offset);
+             return NULL;
+           }
+         ranges = new Vector <Range *> ();
+         for (long i = ind, sz = VecSize (rng_list->ranges); i < sz; i++)
+           {
+             ExtRange *r = rng_list->ranges->get (i);
+             if (r->high == 0)
+               break;
+             ranges->append (new Range (r->low + base_address,
+                                      r->high + base_address));
+           }
+       }
     }
   else
     {
@@ -2227,11 +2301,38 @@ DwrCU::get_ranges ()
                   (long long) low_pc);
        }
     }
-  if (ranges && DUMP_DWARFLIB)
-    ranges->dump (" ");
+  if (ranges)
+    {
+      ranges->sort (rangeCmp);
+      if (DUMP_DWARFLIB)
+       ranges->dump ("DwrCU::get_ranges:");
+    }
   return ranges;
 }
 
+Vector<Symbol *> *
+DwrCU::get_symbols (Vector<Symbol *> *syms)
+{
+  if (syms)
+    syms->reset ();
+  Vector <Range *> *ranges = get_ranges ();
+  if (ranges)
+    {
+      syms = Symbol::find_symbols (symbols, ranges, syms);
+      Destroy (ranges);
+    }
+  if (syms)
+    {
+      Symbol *sym = Symbol::get_symbol (symbols_sorted_by_name,
+                                       get_linkage_name ());
+      if (sym)
+       syms->append (sym);
+    }
+  if (syms && DUMP_ELF_SYM)
+    syms->dump ("DwrCU::get_symbols:");
+  return syms;
+}
+
 void
 DwrCU::set_source (Function *func)
 {
@@ -2239,27 +2340,93 @@ DwrCU::set_source (Function *func)
   func->setLineFirst (lineno);
 
   int fileno = (int) Dwarf_data (DW_AT_decl_file);
+  func->setDefSrc (get_source (fileno));
+}
+
+SourceFile *
+DwrCU::get_source (int fileno)
+{
   if (fileno > 0 && fileno < VecSize (srcFiles))
-    func->setDefSrc (srcFiles->get (fileno));
+    return srcFiles->get (fileno);
+  return NULL;
+}
+
+void
+DwrCU::inherit_prop (int64_t offset, source_t *src)
+{
+  if (src->lineno == 0)
+    src->lineno = (int) Dwarf_data (DW_AT_decl_line);
+  if (src->sf == NULL)
+    src->sf = get_source ((int) Dwarf_data (DW_AT_decl_file));
+
+  int64_t old_offset = dwrTag.offset;
+  if (set_die (offset) == DW_DLV_OK)
+    {
+      if (src->lineno == 0)
+       src->lineno = (int) Dwarf_data (DW_AT_decl_line);
+      if (src->sf == NULL)
+       src->sf = get_source ((int) Dwarf_data (DW_AT_decl_file));
+
+      Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_specification);
+      if (dwrAttr)
+       inherit_prop (dwrAttr->u.offset, src);
+      else
+       {
+         Symbol *sym = Symbol::get_symbol (symbols_sorted_by_name,
+                                         get_linkage_name ());
+         if (sym)
+           update_source (sym, src);
+       }
+    }
+  set_die (old_offset);
+}
+
+void
+DwrCU::set_up_funcs (int64_t offset)
+{
+  // get symbols from DW_AT_ranges, DW_AT_low_pc, DW_AT_linkage_name
+  Vector<Symbol *> *syms = get_symbols (tmp_syms);
+  if (VecSize (syms) == 0)
+    return;
+
+  // Find previous declaration to inherit settings.
+  source_t src = {.lineno = 0, .sf = NULL};
+  inherit_prop (offset, &src);
+
+  for (int i = 0, sz = VecSize (syms); i < sz; i++)
+    {
+      Symbol *sym = syms->get (i);
+      update_source (sym, &src);
+      if (sym->alias)
+       update_source (sym->alias, &src);
+    }
+}
+
+/* Create a function if necessary.
+ * Update the source information  */
+void
+DwrCU::update_source (Symbol *sym, source_t *src)
+{
+  Function *f = sym->createFunction (module);
+  f->setLineFirst (src->lineno);
+  f->setDefSrc (src->sf);
 }
 
 Symbol *
-DwrCU::find_declaration (int64_t offset)
+DwrCU::find_declaration (int64_t offset, source_t *src)
 {
   int64_t old_offset = dwrTag.offset;
   Symbol *sym = NULL;
   if (set_die (offset) == DW_DLV_OK)
     {
+      if (src->lineno == 0)
+       src->lineno = (int) Dwarf_data (DW_AT_decl_line);
+      if (src->sf == NULL)
+       src->sf = get_source ((int) Dwarf_data (DW_AT_decl_file));
+
       sym = Symbol::get_symbol (symbols_sorted_by_name, get_linkage_name ());
       if (sym && sym->func == NULL)
-       {
-         Function *func = sym->createFunction (module);
-         int lineno = (int) Dwarf_data (DW_AT_decl_line);
-         func->setLineFirst (lineno);
-         int fileno = (int) Dwarf_data (DW_AT_decl_file);
-         if (fileno > 0 && fileno < VecSize (srcFiles))
-           func->setDefSrc (srcFiles->get (fileno));
-       }
+       update_source (sym, src);
     }
   set_die (old_offset);
   return sym;
@@ -2344,6 +2511,7 @@ DwrCU::read_data_attr (Dwarf_Half attr, int64_t *retVal)
       case DW_FORM_data16:
       case DW_FORM_udata:
       case DW_FORM_sec_offset:
+      case DW_FORM_implicit_const:
        *retVal = dwrAttr->u.val;
        return DW_DLV_OK;
 
@@ -2577,3 +2745,69 @@ DwrInlinedSubr::dump ()
           (int) level, (long long) abstract_origin, (long long) low_pc,
           (long long) high_pc, (int) file, (int) line);
 }
+
+
+//////////////////////////////////////////////////////////
+//  class Dwr_rng_entry
+Dwr_rng_entry::Dwr_rng_entry ()
+{
+  ranges = new Vector <ExtRange *>();
+}
+
+Dwr_rng_entry::~Dwr_rng_entry ()
+{
+  delete ranges;
+}
+
+void
+Dwr_rng_entry::dump ()
+{
+  Dprintf (DUMP_DWARFLIB, "offset=0x%08llx length=0x%08llx fmt=%d version=%d "
+          "addr_size=%d seg_size=%d offset_entry_count=0x%llx\n",
+          (long long) offset, (long long) (length - offset), fmt64 ? 64 : 32,
+          (int) version, (int) address_size, (int) segment_selector_size,
+          (long long) offset_entry_count);
+  for (long i = 0, sz = VecSize (ranges); i < sz; i++)
+    {
+      ExtRange *p = ranges->get (i);
+      Dprintf (DUMP_DWARFLIB, " %8ld: 0x%08llx 0x%08llx-0x%08llx [%lld-%lld)\n",
+            i, (long long) p->offset, (long long) p->low, (long long) p->high,
+            (long long) p->low, (long long) p->high);
+    }
+}
+
+char *
+Dwr_rng_entry::rng_entry2str (int val)
+{
+  char *s;
+  switch (val)
+    {
+      CASE_S (DW_RLE_end_of_list);
+      CASE_S (DW_RLE_base_address);
+      CASE_S (DW_RLE_start_length);
+      CASE_S (DW_RLE_offset_pair);
+      CASE_S (DW_RLE_start_end);
+      CASE_S (DW_RLE_base_addressx);
+      CASE_S (DW_RLE_startx_endx);
+      CASE_S (DW_RLE_startx_length);
+    default: s = (char *) "???";
+      break;
+    }
+  return s;
+}
+
+template<> void Vector<Dwr_rng_entry *>::dump (const char *msg)
+{
+  if (!DUMP_DWARFLIB)
+    return;
+  if (msg == NULL)
+    msg = "#";
+  Dprintf (1, NTXT ("\n%s Vector<Dwr_rng_entry *> [%lld]\n"), msg, (long long) size ());
+  for (long i = 0, sz = size (); i < sz; i++)
+    {
+      Dwr_rng_entry *p = get (i);
+      Dprintf (1, "  %3ld ", i);
+      p->dump ();
+    }
+}
+
index 230e5517358ff006ae30216533fbef68613e80b4..06b19b84213444659ce3e2c0779f431c3e7b94e8 100644 (file)
@@ -28,6 +28,7 @@ class Dwr_type;
 class Function;
 class Range;
 class SourceFile;
+class Symbol;
 
 template <class ITEM> class Vector;
 template <class ITEM> class DbeArray;
@@ -256,6 +257,45 @@ public:
   Dwr_type *put_dwr_type (Dwr_Tag *dwrTag);
 };
 
+class ExtRange
+{
+public:
+  ExtRange (uint64_t _off, uint64_t _low, uint64_t _high)
+  {
+    offset = _off;
+    low = _low;
+    high = _high;
+  };
+
+  uint64_t offset;
+  uint64_t low;
+  uint64_t high;
+};
+
+class Dwr_rng_entry
+{
+public:
+  Dwr_rng_entry ();
+  ~Dwr_rng_entry ();
+  void dump();
+  static char *rng_entry2str(int val);
+
+  Dwarf_Half version;
+  Dwarf_Small address_size;
+  Dwarf_Small segment_selector_size;
+  int offset_entry_count;
+  uint64_t length;
+  uint64_t offset;
+  bool fmt64;
+  Vector <ExtRange *> *ranges;
+};
+
+typedef struct Source
+{
+  int lineno;
+  SourceFile *sf;
+} source_t;
+
 class DwrCU
 {
 public:
@@ -286,7 +326,12 @@ public:
 private:
   void build_abbrevTable (DwrSec *debug_abbrevSec, uint64_t stmt_list_offset);
   Function *append_Function (Symbol *sym, const char *outerName);
-  Symbol *find_declaration(int64_t offset);
+  void set_up_funcs (int64_t offset);
+  void inherit_prop (int64_t offset, source_t *src);
+  void update_source (Symbol *sym, source_t *prop);
+  Symbol *find_declaration (int64_t offset, source_t *prop);
+  SourceFile *get_source (int fileno);
+  Vector<Symbol *> *get_symbols (Vector<Symbol *> *syms = NULL);
   Vector <Range *> *get_ranges();
   void set_source (Function *func);
   void parse_inlined_subroutine (Dwarf_cnt *ctx);
@@ -317,6 +362,10 @@ private:
   DwrLineRegs *dwrLineReg;
   DbeArray<DwrAbbrevTable> *abbrevTable;
   DbeArray<Dwr_Attr> *abbrevAtForm;
+  Vector<Symbol*> *tmp_syms;    // reused vector for get_symbols()
+  Dwr_rng_entry *rng_list;        // entry in the .debug_rnglists section
+  bool rng_list_inited;
+  uint64_t base_address;        // low_pc in compile_unit
 };
 
 #endif /* _DWARFLIB_H_ */
index be7ad3a2c60ca68ea40269d43ca5c565704953cf..3cdeb9d3e7b79bf05da10e7df08b31a21368d840 100644 (file)
@@ -299,7 +299,7 @@ LoadObject::dump_functions (FILE *out)
        if (fitem->alias && fitem->alias != fitem)
          fprintf (out, "id %6llu, @0x%llx -        %s == alias of '%s'\n",
                   (ull_t) fitem->id, (ull_t) fitem->img_offset,
-                  fitem->get_name (), fitem->alias->get_name ());
+                  fitem->get_mangled_name (), fitem->alias->get_mangled_name ());
        else
          {
            mname = fitem->module ? fitem->module->file_name : noname->file_name;
index ff83949bf2ab6b8b760d7f2bbb69ca1c8ffbfa7c..c6d6473460e4529fd634b7f656a7409ffaa327c6 100644 (file)
@@ -1554,7 +1554,8 @@ Stabs::fixSymtabAlias ()
       for (; i < k; i++)
        {
          sym = SymLst->fetch (i);
-         sym->alias = bestAlias;
+         if (sym != bestAlias)
+           sym->alias = bestAlias;
          sym->size = maxSize;
        }
       i--;
index 82fe788a9e28929b81393c507cf8fa17fec4c20c..8cc578fd2217bff25b896199459ff5996af56613 100644 (file)
@@ -135,13 +135,13 @@ Symbol::sort_by_name (Vector<Symbol *> *syms)
 }
 
 Vector<Symbol *> *
-Symbol::find_symbols (Vector<Symbol*> *syms, Vector<Range *> *ranges)
+Symbol::find_symbols (Vector<Symbol*> *syms, Vector<Range *> *ranges,
+                     Vector<Symbol *> *symbols)
 {
   // 'syms' and 'ranges' must already be sorted.
   // return symbols matched by 'ranges'
   if (VecSize (syms) == 0 || VecSize (ranges) == 0)
     return NULL;
-  Vector<Symbol *> *symbols = new Vector<Symbol*> ();
 
   // Use binary search to find a suitable index in 'syms'
   int ind = 0;
@@ -182,15 +182,7 @@ Symbol::find_symbols (Vector<Symbol*> *syms, Vector<Range *> *ranges)
       if (i >= r_sz)
        break;
     }
-  if (DUMP_ELF_SYM)
-    {
-      syms->dump ( "Symbol::find_symbols: syms");
-      symbols->dump ("Symbol::find_symbols: symbols");
-    }
-  if (symbols->size () != 0)
-    return symbols;
-  delete symbols;
-  return NULL;
+  return symbols;
 }
 
 /* Create and append a new function to the 'module'.
index 25ccecafe7f89c9079cbb87ea2d41d9c548056fe..e9e00602326bc893be88a676eed0099acb007d7a 100644 (file)
@@ -18,6 +18,9 @@
    Foundation, 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
+#ifndef _Symbol_h_
+#define _Symbol_h_
+
 class Function;
 class Module;
 
@@ -54,7 +57,7 @@ public:
 
   // Find symbols in 'syms' matched by 'ranges'.
   static Vector<Symbol *> *find_symbols (Vector<Symbol *> *syms,
-                                        Vector<Range *> *ranges);
+                   Vector<Range *> *ranges, Vector<Symbol *> *symbols = NULL);
   static Vector<Symbol *> *sort_by_name (Vector<Symbol *> *syms);
 
   // Find symbol in CU corresponding to pc or linker_name.
@@ -62,7 +65,7 @@ public:
   static Symbol *get_symbol (Vector<Symbol *> *syms, char *linker_name);
 
   // Create and append a new function to the 'module'.
-  // Copy attributes (size, name, etc) from Simbol,
+  // Copy attributes (size, name, etc) from Symbol,
   Function *createFunction(Module *module);
   void dump (const char *msg = NULL);
 
@@ -77,4 +80,5 @@ public:
   int local_ind;
   int flags;
   bool defined;
-};
\ No newline at end of file
+};
+#endif