Changeset d3318eb in rtems-tools


Ignore:
Timestamp:
Aug 5, 2018, 11:20:58 PM (9 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
f450227
Parents:
367bae8
git-author:
Chris Johns <chrisj@…> (08/05/18 23:20:58)
git-committer:
Chris Johns <chrisj@…> (08/06/18 23:11:29)
Message:

rtemstoolkit/dwarf: C++ object relates fixes and a dump report.

  • Various C++ object fixes that improve stability where data from libdwarf is moving between object instances.
  • Functions now provide better detail with inlined functions picking up attributes from an abstrtact DIE.
  • Dump to a provide stream not stdout.
Location:
rtemstoolkit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • rtemstoolkit/rld-dwarf.cpp

    r367bae8 rd3318eb  
    8383        std::string        what;
    8484        exe_where << "dwarf:" << where;
    85         what = dwarf_errmsg (error);
     85        what = ::dwarf_errmsg (error);
    8686        throw rld::error (what, exe_where.str ());
    8787      }
     
    300300
    301301    void
    302     range::dump ()
     302    range::dump (std::ostream& out) const
    303303    {
    304304      dwarf_ranges_type type_ = type ();
     
    311311      if (type_ <= DW_RANGES_END)
    312312        type_s = type_labels[type_];
    313       std::cout << type_s << '-'
    314                 << std::hex << std::setfill ('0')
    315                 << "0x" << std::setw (8) << addr1 ()
    316                 << ":0x" << std::setw (8) << addr2 ();
     313      out << type_s << '-'
     314          << std::hex << std::setfill ('0')
     315          << "0x" << std::setw (8) << addr1 ()
     316          << ":0x" << std::setw (8) << addr2 ()
     317          << std::dec << std::setfill (' ');
    317318    }
    318319
     
    345346    address_ranges::address_ranges (const address_ranges& orig)
    346347      : debug (orig.debug),
    347         offset (orig.offset)
     348        offset (orig.offset),
     349        dranges (nullptr),
     350        dranges_count (0)
    348351    {
    349352      load (orig.offset);
     
    393396          ::dwarf_ranges_dealloc (debug, dranges, dranges_count);
    394397
     398        ranges_.clear ();
     399
    395400        dranges = nullptr;
    396401        dranges_count = 0;
     
    445450
    446451    void
    447     address_ranges::dump ()
     452    address_ranges::dump (std::ostream& out) const
    448453    {
    449454      bool first = true;
    450       std::cout << '[';
     455      out << '[';
    451456      for (auto& r : ranges_)
    452457      {
    453458        if (!first)
    454           std::cout << ',';
    455         r.dump ();
     459          out << ',';
     460        r.dump (out);
    456461        first = false;
    457462      }
    458       std::cout << ']';
     463      out << ']';
    459464    }
    460465
     
    577582        declaration_ (false),
    578583        inline_ (DW_INL_not_inlined),
     584        entry_pc_ (0),
     585        has_entry_pc_ (false),
    579586        pc_low_ (0),
    580587        pc_high_ (0),
    581         ranges_ (debug)
     588        ranges_ (debug),
     589        call_line_ (0)
    582590    {
    583591      dwarf_bool db;
     
    589597        declaration_ = db ? true : false;
    590598
     599      if (die.attribute (DW_AT_entry_pc, entry_pc_, false))
     600        has_entry_pc_ = true;
     601
    591602      die.attribute (DW_AT_linkage_name, linkage_name_, false);
     603      die.attribute (DW_AT_call_file, decl_file_, false);
     604      die.attribute (DW_AT_call_line, decl_line_, false);
     605      die.attribute (DW_AT_call_file, call_file_, false);
     606      die.attribute (DW_AT_call_line, call_line_, false);
    592607
    593608      if (!die.attribute (DW_AT_inline, inline_, false))
    594609        inline_ = DW_INL_not_inlined;
    595 
    596       if (inline_ == DW_INL_declared_inlined)
    597       {
    598         die_dump_children (die, " +");
    599       }
    600610
    601611      /*
     
    654664              debug_info_entry abst_at_die (debug, abst_at_die_offset);
    655665              if (abst_at_die.attribute (DW_AT_name, name_, false))
     666              {
    656667                found = true;
     668                abst_at_die.attribute (DW_AT_inline, inline_, false);
     669                if (abst_at_die.attribute (DW_AT_external, db, false))
     670                  external_ = db ? true : false;
     671                if (abst_at_die.attribute (DW_AT_declaration, db, false))
     672                  declaration_ = db ? true : false;
     673                abst_at_die.attribute (DW_AT_linkage_name, linkage_name_, false);
     674                abst_at_die.attribute (DW_AT_decl_file, decl_file_, false);
     675                abst_at_die.attribute (DW_AT_decl_line, decl_line_, false);
     676              }
    657677            }
    658678          }
     
    676696                debug_info_entry spec_die (debug, spec_die_offset);
    677697                if (spec_die.attribute (DW_AT_name, name_, false))
     698                {
    678699                  found = true;
     700                  if (spec_die.attribute (DW_AT_external, db, false))
     701                    external_ = db ? true : false;
     702                  if (spec_die.attribute (DW_AT_declaration, db, false))
     703                    declaration_ = db ? true : false;
     704                  spec_die.attribute (DW_AT_linkage_name, linkage_name_, false);
     705                  spec_die.attribute (DW_AT_decl_file, decl_file_, false);
     706                  spec_die.attribute (DW_AT_decl_line, decl_line_, false);
     707                }
    679708              }
    680709            }
    681710          }
    682711        }
    683 
    684         if (die.tag () == DW_TAG_inlined_subroutine)
    685         {
    686           die.attribute (DW_AT_call_file, call_file_, false);
    687         }
    688712      }
    689713
     
    691715      {
    692716        std::cout << "dwarf::function: ";
    693         if (name_.empty ())
    694           std::cout << "NO NAME";
    695         else
    696           std::cout << name_;
    697         if (!has_machine_code ())
    698           std::cout << " NO MACHINE CODE";
    699         else
    700           std::cout << std::hex << std::setfill ('0')
    701                     << " pc_low = 0x" << std::setw (8) << pc_low ()
    702                     << " pc_high = 0x" << std::setw (8) << pc_high ()
    703                     << std::dec << std::setfill (' ');
     717        dump (std::cout);
    704718        std::cout << std::endl;
    705719      }
     720    }
     721
     722    function::function (const function& orig)
     723      : debug (orig.debug),
     724        machine_code_ (orig.machine_code_),
     725        external_ (orig.external_),
     726        declaration_ (orig.declaration_),
     727        inline_ (orig.inline_),
     728        entry_pc_ (orig.entry_pc_),
     729        has_entry_pc_ (orig.has_entry_pc_),
     730        pc_low_ (orig.pc_low_),
     731        pc_high_ (orig.pc_high_),
     732        ranges_ (orig.ranges_),
     733        name_ (orig.name_),
     734        linkage_name_ (orig.linkage_name_),
     735        call_file_ (orig.call_file_),
     736        call_line_ (orig.call_line_)
     737    {
    706738    }
    707739
     
    725757    function::pc_low () const
    726758    {
    727       if (ranges_.empty ())
    728         return pc_low_;
    729       dwarf_address addr = ~0;
    730       for (auto& r : ranges_.get ())
    731       {
    732         if (!r.end () && !r.empty () && r.addr1 () < addr)
    733           addr = r.addr1 ();
    734       }
     759      dwarf_address addr = pc_low_;
     760      if (!ranges_.empty ())
     761      {
     762        addr = ~0;
     763        for (auto& r : ranges_.get ())
     764        {
     765          if (!r.end () && !r.empty () && r.addr1 () < addr)
     766            addr = r.addr1 ();
     767        }
     768      }
     769      if (has_entry_pc_ && addr < entry_pc_)
     770        addr += entry_pc_;
    735771      return addr;
    736772    }
     
    739775    function::pc_high () const
    740776    {
    741       if (ranges_.empty ())
    742         return pc_high_;
    743       dwarf_address addr = 0;
    744       for (auto& r : ranges_.get ())
    745       {
    746         if (!r.end () && !r.empty () && r.addr2 () > addr)
    747           addr = r.addr1 ();
    748       }
     777      dwarf_address addr = pc_high_;
     778      if (!ranges_.empty ())
     779      {
     780        addr = 0;
     781        for (auto& r : ranges_.get ())
     782        {
     783          if (!r.end () && !r.empty () && r.addr2 () > addr)
     784            addr = r.addr2 ();
     785        }
     786      }
     787      if (has_entry_pc_ && addr < entry_pc_)
     788        addr += entry_pc_;
    749789      return addr;
    750790    }
     
    771811    function::is_inlined () const
    772812    {
    773       return inline_ == DW_INL_declared_inlined;
     813      return inline_ == DW_INL_inlined || inline_ == DW_INL_declared_inlined;
    774814    }
    775815
     
    785825      return !name_.empty () && has_machine_code () &&
    786826        addr >= pc_low () && addr <= pc_high ();
     827    }
     828
     829    size_t
     830    function::size () const
     831    {
     832      size_t s = 0;
     833      if (!name_.empty () && has_machine_code ())
     834        s = pc_high () - pc_low ();
     835      return s;
     836    }
     837
     838    function&
     839    function::operator = (const function& rhs)
     840    {
     841      if (this != &rhs)
     842      {
     843        debug = rhs.debug;
     844        machine_code_ = rhs.machine_code_;
     845        external_ = rhs.external_;
     846        declaration_ = rhs.declaration_;
     847        inline_ = rhs.inline_;
     848        entry_pc_ = rhs.entry_pc_;
     849        has_entry_pc_ = rhs.has_entry_pc_;
     850        pc_low_ = rhs.pc_low_;
     851        pc_high_ = rhs.pc_high_;
     852        ranges_ = rhs.ranges_;
     853        name_ = rhs.name_;
     854        linkage_name_ = rhs.linkage_name_;
     855        call_file_ = rhs.call_file_;
     856      }
     857      return *this;
     858    }
     859
     860    void
     861    function::dump (std::ostream& out) const
     862    {
     863      if (name_.empty ())
     864        out << "NO-NAME";
     865      else
     866        out << name_;
     867      out << " ["
     868          << (char) (machine_code_ ? 'M' : '-')
     869          << (char) (external_ ? 'E' : '-')
     870          << (char) (declaration_ ? 'D' : '-')
     871          << (char) (is_inlined () ? 'I' : '-')
     872          << (char) (has_entry_pc_ ? 'P' : '-')
     873          << "] size=" << size ()
     874          << std::hex << std::setfill ('0')
     875          << " (0x" << size () << ')';
     876      if (has_entry_pc_)
     877        out << " epc=0x" << entry_pc_;
     878      out << " pc_low=0x" << pc_low_
     879          << " pc_high=0x" << pc_high_;
     880      if (!linkage_name_.empty ())
     881        out << " ln=" << linkage_name_;
     882      out << std::dec << std::setfill (' ');
     883      if (!call_file_.empty ())
     884        out << " cf=" << call_file_ << ':' << call_line_;
     885      if (!ranges_.empty ())
     886      {
     887        out << " ranges=";
     888        ranges_.dump (out);
     889      }
     890    }
     891
     892    bool
     893    function_compare::operator () (const function& a,
     894                                   const function& b) const
     895    {
     896      bool r = true;
     897
     898      switch (by)
     899      {
     900        case fc_by_name:
     901        default:
     902          r =  a.name () < b.name ();
     903          break;
     904        case fc_by_size:
     905          r = a.size () < b.size ();
     906          break;
     907        case fc_by_address:
     908          r = a.pc_low () < b.pc_low ();
     909          break;
     910      }
     911
     912      return r;
     913    }
     914
     915    function_compare:: function_compare (const function_compare::sort_by by)
     916      : by (by)
     917    {
    787918    }
    788919
     
    801932        offset_ (0)
    802933    {
     934      update ();
    803935    }
    804936
     
    809941        offset_ (offset__)
    810942    {
    811       dwarf_die   ddie;
    812       dwarf_error de;
    813       int         dr;
    814       dr = ::dwarf_offdie (debug, offset_, &ddie, &de);
    815       libdwarf_error_check ("debug_info_entry:debug_info_entry", dr, de);
    816       die = ddie;
     943      update ();
    817944    }
    818945
     
    823950        offset_ (orig.offset_)
    824951    {
    825       if (offset_ != 0)
    826       {
    827         dwarf_die   ddie;
    828         dwarf_error de;
    829         int         dr;
     952      update ();
     953    }
     954
     955    debug_info_entry::~debug_info_entry ()
     956    {
     957      dealloc ();
     958    }
     959
     960    void
     961    debug_info_entry::update ()
     962    {
     963      dwarf_error de;
     964      int         dr;
     965      if (offset_ == 0 && die != nullptr)
     966      {
     967        dr = ::dwarf_dieoffset (die, &offset_, &de);
     968        libdwarf_error_check ("debug_info_entry:update", dr, de);
     969      }
     970      if (offset_ != 0 && die == nullptr)
     971      {
     972        dwarf_die ddie;
    830973        dr = ::dwarf_offdie (debug, offset_, &ddie, &de);
    831         libdwarf_error_check ("debug_info_entry:debug_info_entry", dr, de);
     974        libdwarf_error_check ("debug_info_entry:update", dr, de);
    832975        die = ddie;
    833976      }
    834     }
    835 
    836     debug_info_entry::~debug_info_entry ()
    837     {
    838       dealloc ();
     977      valid ();
     978    }
     979
     980    bool
     981    debug_info_entry::valid (bool fatal) const
     982    {
     983      bool r = die == nullptr || offset_ == 0;
     984      if (r && fatal)
     985      {
     986        std::string what = "no DIE and offset";
     987        if (offset_ != 0)
     988          what = "no DIE";
     989        else if (die != nullptr)
     990          what = "no offset";
     991        throw rld::error (what, "debug_info_entry:valid");
     992      }
     993      return r;
    839994    }
    840995
     
    8681023        offset_ = rhs.offset_;
    8691024        rhs.die = nullptr;
     1025        if (offset_ != 0 || die != nullptr)
     1026          update ();
    8701027      }
    8711028      return *this;
     
    8781035      if (offset__ != 0)
    8791036      {
    880         dwarf_die   ddie;
    881         dwarf_error de;
    882         int         dr;
    8831037        offset_ = offset__;
    8841038        tag_ = 0;
    885         dr = ::dwarf_offdie (debug, offset_, &ddie, &de);
    886         libdwarf_error_check ("debug_info_entry:operator=", dr, de);
    887         die = ddie;
     1039        update ();
    8881040      }
    8891041      return *this;
     
    9111063        int         dr;
    9121064        dr = ::dwarf_tag (die, &tag_, &de);
    913         libdwarf_error_check ("debug_info_entry:debug_info_entry", dr, de);
     1065        libdwarf_error_check ("debug_info_entry:tag", dr, de);
    9141066      }
    9151067      return tag_;
     
    9241076        int         dr;
    9251077        dr = ::dwarf_dieoffset (die, &offset_, &de);
    926         libdwarf_error_check ("debug_info_entry:debug_info_entry", dr, de);
     1078        libdwarf_error_check ("debug_info_entry:offset", dr, de);
    9271079      }
    9281080      return offset_;
     
    10581210    debug_info_entry::get_child (debug_info_entry& child_die)
    10591211    {
     1212      debug_info_entry ret_die (get_debug ());
    10601213      dwarf_error      de;
    10611214      int              dr;
    1062       dr = ::dwarf_child (die, child_die, &de);
     1215      dr = ::dwarf_child (die, ret_die, &de);
     1216      if (dr == DW_DLV_OK)
     1217      {
     1218        ret_die.update ();
     1219        child_die = ret_die;
     1220        child_die.valid ();
     1221      }
    10631222      return dr == DW_DLV_OK;
    10641223    }
    10651224
    10661225    bool
    1067     debug_info_entry::get_sibling (debug_info_entry& sibling_die)
    1068     {
     1226    debug_info_entry::has_child () const
     1227    {
     1228      debug_info_entry ret_die (get_debug ());
    10691229      dwarf_error      de;
    10701230      int              dr;
    1071       dr = ::dwarf_siblingof (debug, die, sibling_die, &de);
     1231      dr = ::dwarf_child (die, ret_die, &de);
     1232      return dr == DW_DLV_OK;
     1233    }
     1234
     1235    bool
     1236    debug_info_entry::get_sibling (debug_info_entry& sibling_die)
     1237    {
     1238      debug_info_entry ret_die (get_debug ());
     1239      dwarf_error      de;
     1240      int              dr;
     1241      dr = ::dwarf_siblingof (debug, die, ret_die, &de);
    10721242      if (dr == DW_DLV_NO_ENTRY)
    10731243        return false;
    10741244      libdwarf_error_check ("compilation_unit::sibling", dr, de);
     1245      sibling_die = ret_die;
    10751246      return true;
    10761247    }
    10771248
     1249    bool
     1250    debug_info_entry::has_sibling () const
     1251    {
     1252      debug_info_entry ret_die (get_debug ());
     1253      dwarf_error      de;
     1254      int              dr;
     1255      dr = ::dwarf_siblingof (debug, die, ret_die, &de);
     1256      return dr == DW_DLV_OK;
     1257    }
     1258
    10781259    file&
    1079     debug_info_entry::get_debug ()
     1260    debug_info_entry::get_debug () const
    10801261    {
    10811262      return debug;
     
    10921273
    10931274    void
    1094     debug_info_entry::dump (std::string prefix, bool newline)
    1095     {
     1275    debug_info_entry::dump (std::ostream& out,
     1276                            std::string   prefix,
     1277                            bool          newline)
     1278    {
     1279      std::string level_prefix;
     1280
     1281      for (auto c : prefix)
     1282      {
     1283        switch (c)
     1284        {
     1285          case '+':
     1286            c = '|';
     1287            break;
     1288          case '-':
     1289            c = ' ';
     1290            break;
     1291          default:
     1292            break;
     1293        }
     1294        level_prefix += c;
     1295      }
     1296
    10961297      const char* s;
    10971298      ::dwarf_get_TAG_name (tag (), &s);
    1098       std::cout << prefix << s << std::endl;
     1299      out << level_prefix.substr (0, level_prefix.length () - 1)
     1300          << "+- " << s << std::endl;
    10991301
    11001302      dwarf_attribute* attributes;
     
    11181320          dwarf_get_AT_name (attr, &s);
    11191321          if (a > 0)
    1120             std::cout << std::endl;
    1121           std::cout << prefix << " - " << s << " (" << attr << ") [" << f << ']';
     1322            out << std::endl;
     1323          out << level_prefix << " +- "
     1324              << s << " (" << attr << ") [" << f << ']';
    11221325          debug_info_entry v_die (debug);
    11231326          address_ranges   v_ranges (debug);
     
    11401343              dr = ::dwarf_attrval_unsigned (die, attr, &v_unsigned, &de);
    11411344              libdwarf_error_check ("debug_info_entry::dump", dr, de);
    1142               std::cout << " : "
    1143                         << std::hex << std::setfill ('0')
    1144                         << std::setw (8) << v_unsigned
    1145                         << std::dec << std::setfill (' ')
    1146                         << " (" << v_unsigned << ')';
     1345              s = "";
     1346              switch (attr)
     1347              {
     1348                case DW_AT_inline:
     1349                  dwarf_get_INL_name(v_unsigned, &s);
     1350                  break;
     1351                default:
     1352                  break;
     1353              }
     1354              out << " : "
     1355                  << std::hex << std::setfill ('0')
     1356                  << std::setw (8) << v_unsigned
     1357                  << std::dec << std::setfill (' ')
     1358                  << " (" << v_unsigned << ") " << s;
    11471359              break;
    11481360            case DW_FORM_ref1:
     
    11531365              dr = ::dwarf_global_formref (attributes[a], &v_offset, &de);
    11541366              libdwarf_error_check ("debug_info_entry::dump", dr, de);
    1155               std::cout << " : "
    1156                         << std::hex << std::setfill ('0')
    1157                         << std::setw (8) << v_offset
    1158                         << std::dec << std::setfill (' ')
    1159                         << " (" << v_offset << ')';
     1367              out << " : "
     1368                  << std::hex << std::setfill ('0')
     1369                  << std::setw (8) << v_offset
     1370                  << std::dec << std::setfill (' ')
     1371                  << " (" << v_offset << ')';
    11601372              switch (attr)
    11611373              {
     
    11631375                case DW_AT_specification:
    11641376                  v_die = v_offset;
    1165                   std::cout << std::endl;
    1166                   v_die.dump (' ' + prefix, false);
     1377                  out << std::endl;
     1378                  v_die.dump (out, prefix + " |  ", false);
    11671379                  break;
    11681380                default:
     
    11761388              dr = ::dwarf_attrval_flag (die, attr, &v_bool, &de);
    11771389              libdwarf_error_check ("debug_info_entry::dump", dr, de);
    1178               std::cout << " : " << v_bool;
     1390              out << " : " << v_bool;
    11791391              break;
    11801392              break;
     
    11831395              dr = ::dwarf_attrval_string (die, attr, &s, &de);
    11841396              libdwarf_error_check ("debug_info_entry::dump", dr, de);
    1185               std::cout << " : " << s;
     1397              out << " : " << s;
    11861398              break;
    11871399            case DW_FORM_sec_offset:
     
    11911403                  dr = ::dwarf_global_formref (attributes[a], &v_offset, &de);
    11921404                  libdwarf_error_check ("debug_info_entry::dump", dr, de);
    1193                   std::cout << ' ';
     1405                  out << ' ';
    11941406                  v_ranges.load (v_offset);
    1195                   v_ranges.dump ();
     1407                  v_ranges.dump (out);
    11961408                  break;
    11971409                default:
     
    12071419        }
    12081420        if (newline)
    1209           std::cout << std::endl;
    1210       }
    1211     }
    1212 
    1213     void
    1214     die_dump_children (debug_info_entry die,
    1215                        std::string      prefix,
    1216                        int              nesting,
    1217                        int              depth)
     1421          out <<  std::endl;
     1422      }
     1423    }
     1424
     1425    void
     1426    die_dump_children (debug_info_entry& die,
     1427                       std::ostream&     out,
     1428                       std::string       prefix,
     1429                       int               depth,
     1430                       int               nesting)
    12181431    {
    12191432      debug_info_entry child (die.get_debug ());
    12201433      if (die.get_child (child))
    1221         die_dump (child, prefix, nesting, depth);
    1222     }
    1223 
    1224     void
    1225     die_dump (debug_info_entry die,
    1226               std::string      prefix,
    1227               int              nesting,
    1228               int              depth)
     1434        die_dump (child, out, prefix, depth, nesting);
     1435    }
     1436
     1437    void
     1438    die_dump (debug_info_entry& die,
     1439              std::ostream&     out,
     1440              std::string       prefix,
     1441              int               depth,
     1442              int               nesting)
    12291443    {
    12301444      ++nesting;
    12311445
    1232       for (int n = 0; n < nesting; ++n)
    1233         prefix += ' ';
    1234 
    12351446      while (true)
    12361447      {
    1237         die.dump (prefix);
     1448        char v = die.has_sibling () || die.has_child () ? '+' : ' ';
     1449
     1450        die.dump (out, prefix + v);
    12381451
    12391452        if (depth < 0 || nesting < depth)
    1240           die_dump_children (die, prefix);
     1453          die_dump_children (die, out, prefix + "+   ", depth, nesting);
    12411454
    12421455        debug_info_entry next (die.get_debug ());
     
    14231636    {
    14241637      debug_info_entry die (debug, die_offset);
    1425       debug_info_entry ret_die (debug);
    1426       dwarf_error      de;
    1427       int              dr;
    1428       dr = ::dwarf_child(die, ret_die, &de);
    1429       if (dr == DW_DLV_OK)
    1430         load_functions (ret_die);
     1638      debug_info_entry child (debug);
     1639      if (die.get_child (child))
     1640        load_functions (child);
    14311641    }
    14321642
     
    14411651        {
    14421652          function func (debug, die);
    1443           if (func.has_machine_code () &&
    1444               func.pc_low () >= pc_low_ && func.pc_high () <= pc_high_)
    1445           {
    1446             functions_.push_back (func);
    1447           }
    1448         }
    1449 
    1450         debug_info_entry ret_die (debug);
    1451         dwarf_error      de;
    1452         int              dr;
    1453 
    1454         dr = ::dwarf_child(die, ret_die, &de);
    1455         if (dr == DW_DLV_OK)
    1456           load_functions (ret_die);
    1457 
    1458         dr = ::dwarf_siblingof (debug, die, ret_die, &de);
    1459         if (dr == DW_DLV_NO_ENTRY)
     1653          functions_.push_back (func);
     1654        }
     1655
     1656        debug_info_entry next (die.get_debug ());
     1657
     1658        if (die.get_child (next))
     1659          load_functions (next);
     1660
     1661        if (!die.get_sibling (next))
    14601662          break;
    1461         libdwarf_error_check ("compilation_unit:load_functions", dr, de);
    1462 
    1463         die = ret_die;
     1663
     1664        die = next;
    14641665      }
    14651666    }
     
    15501751
    15511752    void
    1552     compilation_unit::dump_die ()
     1753    compilation_unit::dump_die (std::ostream&     out,
     1754                                const std::string prefix,
     1755                                int               depth)
    15531756    {
    15541757      debug_info_entry die (debug, die_offset);
    1555       std::cout << "CU @ 0x" << std::hex << offset_ << std::dec << std::endl;
    1556       die_dump_children (die, "");
     1758      out << "CU @ 0x" << std::hex << offset_ << std::dec << std::endl;
     1759      die_dump (die, out, prefix, depth);
    15571760    }
    15581761
     
    15711774    }
    15721775
    1573     source_flags_compare:: source_flags_compare (bool by_basename)
     1776    source_flags_compare::source_flags_compare (bool by_basename)
    15741777      : by_basename (by_basename)
    15751778    {
     
    16641867
    16651868    void
     1869    file::dump (std::ostream&     out,
     1870                const std::string prefix,
     1871                int               depth)
     1872    {
     1873      dwarf_unsigned cu_offset = 0;
     1874
     1875      while (true)
     1876      {
     1877        dwarf_unsigned cu_next_offset = 0;
     1878        dwarf_error    de;
     1879        int            dr;
     1880
     1881        dr = ::dwarf_next_cu_header_c(debug, 1,
     1882                                      nullptr, nullptr, nullptr,  nullptr,
     1883                                      nullptr, nullptr, nullptr,  nullptr,
     1884                                      &cu_next_offset, &de);
     1885        if (dr != DW_DLV_OK)
     1886          break;
     1887
     1888        /*
     1889         * Find the CU DIE by asking the CU for it's first DIE.
     1890         */
     1891        debug_info_entry die (*this);
     1892
     1893        while (true)
     1894        {
     1895          debug_info_entry sibling (*this);
     1896          if (!die.get_sibling (sibling))
     1897            break;
     1898          if (sibling.tag () == DW_TAG_compile_unit)
     1899            die_dump (sibling, out, prefix, depth);
     1900          die = sibling;
     1901        }
     1902
     1903        cu_offset = cu_next_offset;
     1904      }
     1905    }
     1906
     1907    void
    16661908    file::load_debug ()
    16671909    {
  • rtemstoolkit/rld-dwarf.h

    r367bae8 rd3318eb  
    2626#define _RLD_DWARF_H_
    2727
     28#include <iostream>
     29
    2830#include <rld.h>
    2931#include <rld-dwarf-types.h>
     
    153155       * Dump the range.
    154156       */
    155       void dump ();
     157      void dump (std::ostream& out) const;
    156158
    157159    private:
     
    202204       * Dump the address ranges.
    203205       */
    204       void dump ();
     206      void dump (std::ostream& out) const;
    205207
    206208    private:
     
    282284    public:
    283285      function (file& debug, debug_info_entry& die);
     286      function (const function& orig);
    284287      ~function ();
    285288
     
    339342       */
    340343      bool inside (dwarf_address addr) const;
     344
     345      /**
     346       * Size of the function.
     347       */
     348      size_t size () const;
     349
     350      /**
     351       * Assigment operator.
     352       */
     353      function& operator = (const function& rhs);
     354
     355      /**
     356       * Dump the function.
     357       */
     358      void dump (std::ostream& out) const;
    341359
    342360    private:
     
    346364      bool           external_;
    347365      bool           declaration_;
     366      bool           prototyped_;
    348367      dwarf_unsigned inline_;
     368      dwarf_unsigned entry_pc_;
     369      bool           has_entry_pc_;
    349370      dwarf_unsigned pc_low_;
    350371      dwarf_unsigned pc_high_;
     
    352373      std::string    name_;
    353374      std::string    linkage_name_;
     375      std::string    decl_file_;
     376      dwarf_unsigned decl_line_;
    354377      std::string    call_file_;
     378      dwarf_unsigned call_line_;
    355379    };
    356380
    357381    typedef std::vector < function > functions;
     382
     383    /**
     384     * Worker to sort the functions.
     385     */
     386    struct function_compare
     387    {
     388      enum sort_by
     389      {
     390        fc_by_name,
     391        fc_by_size,
     392        fc_by_address
     393      };
     394
     395      const sort_by by;
     396
     397      bool operator () (const function& a, const function& b) const;
     398
     399      function_compare (sort_by by = fc_by_name);
     400    };
    358401
    359402    /**
     
    379422
    380423      /**
     424       * Is the DIE valid?
     425       */
     426      bool valid (bool fatal = true) const;
     427
     428      /**
    381429       * Get the DIE.
    382430       */
     
    476524
    477525      /**
     526       * Has a child?
     527       */
     528      bool has_child () const;
     529
     530      /**
    478531       * Get the silbing
    479532       */
     
    481534
    482535      /**
     536       * Has a silbing?
     537       */
     538      bool has_sibling () const;
     539
     540      /**
    483541       * Get the debug info for this DIE.
    484542       */
    485       file& get_debug ();
     543      file& get_debug () const;
    486544
    487545      /**
     
    493551       * Dump this DIE.
    494552       */
    495       void dump (std::string prefix, bool newline = true);
     553      void dump (std::ostream& out,
     554                 std::string   prefix,
     555                 bool          newline = true);
    496556
    497557    private:
     558
     559      /**
     560       * Update the internal DIE and offset values.
     561       */
     562      void update ();
    498563
    499564      file&        debug;
     
    507572     * Dump the DIE and all it's children and siblings.
    508573     */
    509     void die_dump_children (debug_info_entry die,
    510                             std::string      prefix,
    511                             int              nesting = 0,
    512                             int              depth = -1);
     574    void die_dump_children (debug_info_entry& die,
     575                            std::ostream&     out,
     576                            std::string       prefix,
     577                            int               depth = -1,
     578                            int               nesting = 0);
    513579
    514580    /**
    515581     * Dump the DIE and all it's children and siblings.
    516582     */
    517     void die_dump (debug_info_entry die,
    518                    std::string      prefix,
    519                    int              nesting = 0,
    520                    int              depth = -1);
     583    void die_dump (debug_info_entry& die,
     584                   std::ostream&     out,
     585                   std::string       prefix,
     586                   int               depth = -1,
     587                   int               nesting = 0);
    521588
    522589    /**
     
    589656       * Output the DIE tree.
    590657       */
    591       void dump_die ();
     658      void dump_die (std::ostream&     out,
     659                     const std::string prefix = " ",
     660                     int               depth = -1);
    592661
    593662    private:
     
    704773
    705774      /**
     775       * Get the producer sources from the compilation units.
     776       */
     777      void get_producer_sources (producer_sources& producers);
     778
     779      /**
     780       * Does the function exist.
     781       */
     782      bool function_valid (std::string&name);
     783
     784      /**
     785       * Get the function given a name. Raises an exception if not found.
     786       */
     787      function& get_function (std::string& name);
     788
     789      /**
    706790       * Get the function given an address.
    707791       */
     
    710794
    711795      /**
    712        * Get the producer sources from the compilation units.
    713        */
    714       void get_producer_sources (producer_sources& producers);
    715 
    716       /**
    717796       * Get the DWARF debug information reference.
    718797       */
     
    733812       */
    734813      const std::string& name () const;
     814
     815      /**
     816       * Dump the DWARF data.
     817       */
     818      void dump (std::ostream&     out,
     819                 const std::string prefix = " ",
     820                 int               depth = -1);
    735821
    736822    private:
Note: See TracChangeset for help on using the changeset viewer.