Changeset 1cab261 in rtems-tools


Ignore:
Timestamp:
May 24, 2018, 6:00:09 AM (17 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
0f481ad
Parents:
1f1a10f
git-author:
Chris Johns <chrisj@…> (05/24/18 06:00:09)
git-committer:
Chris Johns <chrisj@…> (06/18/18 02:26:16)
Message:

rtemstoolkit/dwarf: Fixes for getting source lines.

Location:
rtemstoolkit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • rtemstoolkit/rld-dwarf.cpp

    r1f1a10f r1cab261  
    8686    }
    8787
     88    address::address (const address& orig, const sources& source)
     89      : addr (orig.addr),
     90        source (&source),
     91        source_index (orig.source_index),
     92        source_line (orig.source_line),
     93        begin_statement (orig.begin_statement),
     94        block (orig.block),
     95        end_sequence (orig.end_sequence)
     96    {
     97    }
     98
     99    address::address (const address& orig, dwarf_address addr)
     100      : addr (addr),
     101        source (orig.source),
     102        source_index (orig.source_index),
     103        source_line (orig.source_line),
     104        begin_statement (orig.begin_statement),
     105        block (orig.block),
     106        end_sequence (orig.end_sequence)
     107    {
     108    }
     109
    88110    address::address (const address& orig)
    89111      : addr (orig.addr),
     
    174196    }
    175197
     198    bool
     199    address::operator < (const address& rhs) const
     200    {
     201      return addr < rhs.addr;
     202    }
     203
    176204    line_addresses::line_addresses (file&             debug,
    177205                                    debug_info_entry& die)
     
    187215    }
    188216
    189     line_addresses::line_addresses (line_addresses&& orig)
    190       : debug (orig.debug),
    191         lines (orig.lines),
    192         count_ (orig.count_)
    193     {
    194       orig.lines = nullptr;
    195       orig.count_ = 0;
    196     }
    197 
    198217    line_addresses::~line_addresses ()
    199218    {
     
    221240    }
    222241
    223     sources::sources (file& debug, debug_info_entry& die)
     242    sources::sources (file& debug, dwarf_offset die_offset)
    224243      : debug (debug),
    225244        source (nullptr),
    226245        count (0),
    227         die_offset (die.offset ())
    228     {
     246        die_offset (die_offset)
     247    {
     248      debug_info_entry die (debug, die_offset);
    229249      die.source_files (source, count);
    230250    }
     
    244264    }
    245265
    246     sources::sources (sources&& orig)
    247       : debug (orig.debug),
    248         source (orig.source),
    249         count (orig.count),
    250         die_offset (orig.die_offset)
    251     {
    252       orig.source = nullptr;
    253       orig.count = 0;
    254     }
    255 
    256266    sources::~sources ()
    257267    {
     
    264274      if (index <= 0 || index > count)
    265275        return "unknown";
    266       return source[index - 1];
     276      return std::string (source[index - 1]);
    267277    }
    268278
     
    275285         * The elftoolchain cleans the memory up and there is no compatible
    276286         * call we can put here so adding the required code causes is a double
    277          * free results in a crash.
     287         * free resulting in a crash.
    278288         */
    279289        if (false)
     
    331341    }
    332342
    333     debug_info_entry::debug_info_entry (debug_info_entry&& orig)
    334       : debug (orig.debug),
    335         die (orig.die),
    336         tag_ (orig.tag_),
    337         offset_ (orig.offset_)
    338     {
    339       orig.die = nullptr;
    340       orig.tag_ = 0;
    341       orig.offset_ = 0;
    342     }
    343 
    344343    debug_info_entry::~debug_info_entry ()
    345344    {
    346       if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
    347         std::cout << "dwarf::debug_info_entry::~debug_info_entry" << std::endl;
    348345      dealloc ();
    349346    }
     
    493490        pc_low_ (0),
    494491        pc_high_ (0),
    495         source_ (debug, die),
    496         die_offset (die.offset ())
     492        die_offset (die.offset ()),
     493        source_ (debug, die_offset)
    497494    {
    498495      die.attribute (DW_AT_name, name_);
     
    505502      if (!die.attribute (DW_AT_high_pc, pc_high_, false))
    506503        pc_high_ = ~0U;
     504
     505      if (pc_high_ < pc_low_)
     506        pc_high_ += pc_low_;
    507507
    508508      if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
     
    523523      line_addresses lines (debug, die);
    524524      dwarf_address  pc = 0;
     525      bool           seq_check = true;
     526      dwarf_address  seq_base = 0;
    525527
    526528      for (size_t l = 0; l < lines.count (); ++l)
    527529      {
    528         address       addr (source_, lines[l]);
    529         dwarf_address loc = addr.location ();
    530         if (inside (loc) && loc >= pc)
     530        address       daddr (source_, lines[l]);
     531        dwarf_address loc = daddr.location ();
     532        /*
     533         * A CU's line program can have some sequences at the start where the
     534         * address is incorrectly set to 0. Ignore these entries.
     535         */
     536        if (pc == 0)
     537        {
     538          if (!seq_check)
     539          {
     540            seq_check = daddr.is_an_end_sequence ();
     541            continue;
     542          }
     543          if (loc == 0)
     544          {
     545            seq_check = false;
     546            continue;
     547          }
     548        }
     549        /*
     550         * A sequence of line program instruction may set the address to 0. Use
     551         * the last location from the previous sequence as the sequence's base
     552         * address. All locations will be offset from the that base until the
     553         * end of this sequence.
     554         */
     555        if (loc == 0 && seq_base == 0)
     556          seq_base = pc;
     557        if (seq_base != 0)
     558          loc += seq_base;
     559        if (daddr.is_an_end_sequence ())
     560          seq_base = 0;
     561        address addr (daddr, loc);
     562        if (loc >= pc_low_ && loc < pc_high_)
    531563        {
    532564          pc = loc;
    533           addr_lines_[addr.location ()] = addr;
    534           if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
    535           {
    536             std::cout << "dwarf::compilation_unit: "
    537                       << std::hex << std::setw (8) << addr.location () << std::dec
    538                       << " - "
    539                       << (char) (addr.is_a_begin_statement () ? 'B' : '.')
    540                       << (char) (addr.is_in_a_block () ? 'I' : '.')
    541                       << (char) (addr.is_an_end_sequence () ? 'E' : '.')
    542                       << " - "
    543                       << rld::path::basename (addr.path ())
    544                       << ':' << addr.line ()
    545                       << std::endl;
    546           }
    547         }
    548       }
    549     }
    550 
    551     compilation_unit::compilation_unit (compilation_unit&& orig)
    552       : debug (orig.debug),
    553         offset_ (orig.offset_),
    554         name_ (orig.name_),
    555         producer_ (orig.producer_),
    556         pc_low_ (orig.pc_low_),
    557         pc_high_ (orig.pc_high_),
    558         source_ (std::move (orig.source_)),
    559         addr_lines_ (orig.addr_lines_),
    560         die_offset (orig.die_offset)
    561     {
    562       orig.name_.clear ();
    563       orig.producer_.clear ();
    564       orig.offset_ = 0;
    565       orig.die_offset = 0;
    566       orig.pc_low_ = 0;
    567       orig.pc_high_ = 0;
     565          addr_lines_.push_back (addr);
     566        }
     567      }
     568
     569      if (!addr_lines_.empty ())
     570      {
     571        std::stable_sort (addr_lines_.begin (), addr_lines_.end ());
     572        if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
     573        {
     574          auto first = addr_lines_.begin ();
     575          auto last = addr_lines_.end () - 1;
     576          std::cout << "dwarf::compilation_unit: line_low=0x"
     577                    << std::hex
     578                    << std::setw (8) << first->location ()
     579                    << ", line_high=0x"
     580                    << std::setw (8) << last->location ()
     581                    << std::dec
     582                    << std::endl;
     583        }
     584      }
     585
     586      if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
     587      {
     588        int lc = 0;
     589        for (auto& l : addr_lines_)
     590        {
     591          std::cout << "dwarf::compilation_unit: " << std::setw (3) << ++lc
     592                    << ": 0x"
     593                    << std::hex << std::setw (8) << l.location () << std::dec
     594                    << " - "
     595                    << (char) (l.is_a_begin_statement () ? 'B' : '.')
     596                    << (char) (l.is_in_a_block () ? 'I' : '.')
     597                    << (char) (l.is_an_end_sequence () ? 'E' : '.')
     598                    << " - "
     599                    << rld::path::basename (l.path ())
     600                    << ':' <<l.line ()
     601                    << std::endl;
     602        }
     603      }
    568604    }
    569605
     
    575611        pc_low_ (orig.pc_low_),
    576612        pc_high_ (orig.pc_high_),
    577         source_ (orig.source_),
    578         addr_lines_ (orig.addr_lines_),
    579         die_offset (orig.die_offset)
    580     {
     613        die_offset (orig.die_offset),
     614        source_ (debug, die_offset)
     615    {
     616      for (auto& line : orig.addr_lines_)
     617        addr_lines_.push_back (address (line, source_));
     618      std::stable_sort (addr_lines_.begin (), addr_lines_.end ());
    581619    }
    582620
    583621    compilation_unit::~compilation_unit ()
    584622    {
    585       if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
    586         std::cout << "dwarf::compilation_unit::~compilation_unit: " << name_ << std::endl;
    587623    }
    588624
     
    615651                                  address&            addr_line)
    616652    {
    617       if (addr_lines_.find (addr) == addr_lines_.end ())
    618           return false;
    619       addr_line = addr_lines_[addr];
    620       return true;
     653      if (!addr_lines_.empty () && inside (addr))
     654      {
     655        address last_loc;
     656        for (auto& loc : addr_lines_)
     657        {
     658          if (addr <= loc.location ())
     659          {
     660            if (addr == loc.location ())
     661              addr_line = loc;
     662            else
     663              addr_line = last_loc;
     664            return addr_line.valid ();
     665          }
     666          last_loc = loc;
     667        }
     668      }
     669      return false;
    621670    }
    622671
     
    624673    compilation_unit::inside (dwarf_unsigned addr) const
    625674    {
     675      if (!addr_lines_.empty ())
     676      {
     677        auto first = addr_lines_.begin ();
     678        auto last = addr_lines_.end () - 1;
     679        return first->location () <= addr && addr <= last->location ();
     680      }
    626681      return addr >= pc_low_ && addr < pc_high_;
    627     }
    628 
    629     compilation_unit&
    630     compilation_unit::operator = (compilation_unit&& rhs)
    631     {
    632       if (this != &rhs)
    633       {
    634         debug = rhs.debug;
    635         offset_ = rhs.offset_;
    636         name_ = rhs.name_;
    637         producer_ = rhs.producer_;
    638         source_ = std::move (rhs.source_);
    639         addr_lines_ = std::move (rhs.addr_lines_),
    640         pc_low_ = rhs.pc_low_;
    641         pc_high_ = rhs.pc_high_;
    642         die_offset = rhs.die_offset;
    643         rhs.offset_ = 0;
    644         rhs.name_.clear ();
    645         rhs.pc_low_ = -1;
    646         rhs.pc_high_ = -1;
    647         rhs.die_offset = 0;
    648       }
    649       return *this;
    650682    }
    651683
     
    664696        name_ = rhs.name_;
    665697        producer_ = rhs.producer_;
    666         debug_info_entry die (debug, rhs.offset_);
    667         source_ = sources (debug, die);
    668         addr_lines_ = addresses (rhs.addr_lines_);
     698        source_ = sources (debug, die_offset);
     699        for (auto& line : rhs.addr_lines_)
     700          addr_lines_.push_back (address (line, source_));
    669701        pc_low_ = rhs.pc_low_;
    670702        pc_high_ = rhs.pc_high_;
     
    845877        if (r)
    846878        {
    847           if (match.valid ())
     879          if (match.valid () &&
     880              (match.is_an_end_sequence () || !!line.is_an_end_sequence ()))
    848881          {
    849             if (match.is_an_end_sequence ())
    850             {
    851               match = line;
    852             }
    853             else if (!line.is_an_end_sequence ())
    854             {
    855               match = line;
    856             }
     882            match = line;
     883          }
     884          else
     885          {
     886            match = line;
    857887          }
    858888        }
  • rtemstoolkit/rld-dwarf.h

    r1f1a10f r1cab261  
    4747    public:
    4848      address (const sources& source, dwarf_line& line);
     49      address (const address& orig, const sources& source);
     50      address (const address& orig, dwarf_address addr);
    4951      address (const address& orig);
    5052      address ();
     
    9092       */
    9193      address& operator = (const address& rhs);
     94
     95      /**
     96       * Less than operator to allow sorting.
     97       */
     98      bool operator < (const address& rhs) const;
    9299
    93100    private:
     
    103110
    104111    /**
    105      * The addresses table is a map of the addresses in a CU to their line
    106      * number.
    107      */
    108     typedef std::map < const dwarf_address, address > addresses;
    109 
     112     * The addresses table is a vector sorted from low to high addresses..
     113     */
     114    typedef std::vector < address > addresses;
    110115
    111116    /**
     
    116121    public:
    117122      line_addresses (file& debug, debug_info_entry& die);
    118       line_addresses (line_addresses&& orig);
    119123      ~line_addresses ();
    120124
     
    145149    {
    146150    public:
    147       sources (file& debug, debug_info_entry& die);
     151      sources (file& debug, dwarf_offset die_offset);
    148152      sources (const sources& orig);
    149       sources (sources&& orig);
     153      //sources (sources&& orig);
    150154      ~sources ();
    151155
     
    187191      debug_info_entry (file& debug, dwarf_die& die);
    188192      debug_info_entry (file& debug, dwarf_offset offset);
    189       debug_info_entry (debug_info_entry&& orig);
    190193
    191194      /**
     
    278281                        dwarf_offset      offset);
    279282      compilation_unit (const compilation_unit& orig);
    280       compilation_unit (compilation_unit&& orig);
    281283      ~compilation_unit ();
    282284
     
    310312
    311313      /**
    312        * Is the address inside the CU? Becareful using this because not all CUs
    313        * have these attributes set and the address range will be the entire
    314        * address space.
     314       * Is the address inside the CU? If the PC low and high attributes are
     315       * valid they are used or the lines are checked.
    315316       */
    316317      bool inside (dwarf_unsigned addr) const;
    317 
    318       /**
    319        * Move assignment operator.
    320        */
    321       compilation_unit& operator = (compilation_unit&& rhs);
    322318
    323319      /**
     
    335331      dwarf_unsigned pc_high_;    ///< The PC high address.
    336332
     333      dwarf_offset   die_offset;  ///< The offset of the DIE in the image.
     334
    337335      sources        source_;     ///< Sources table for this CU.
    338336      addresses      addr_lines_; ///< Address table.
    339 
    340       dwarf_offset   die_offset;  ///< The offset of the DIE in the image.
    341337    };
    342338
Note: See TracChangeset for help on using the changeset viewer.