diff options
-rw-r--r-- | libdw/c++/dwarf | 28 | ||||
-rw-r--r-- | libdw/c++/values.cc | 71 |
2 files changed, 56 insertions, 43 deletions
diff --git a/libdw/c++/dwarf b/libdw/c++/dwarf index 085f0f92..8342dc78 100644 --- a/libdw/c++/dwarf +++ b/libdw/c++/dwarf @@ -1,5 +1,5 @@ /* -*- C++ -*- interfaces for libdw. - Copyright (C) 2009-2010 Red Hat, Inc. + Copyright (C) 2009-2011 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -1325,24 +1325,25 @@ namespace elfutils ::Dwarf_Addr _m_begin; // XXX reloc ::Dwarf_Addr _m_end; // XXX reloc ::Dwarf_CU *_m_cu; - ptrdiff_t _m_offset; + unsigned char *_m_readptr; - const_iterator (Dwarf_Attribute *, ptrdiff_t offset); + static unsigned char *formptr (int secndx, Dwarf_Attribute *); + const_iterator (int secndx, Dwarf_Attribute *, unsigned char *readptr); public: // Default constructor: only valid for operator=. inline const_iterator () - : _m_base (-1), _m_begin (0), _m_end (0), _m_cu (NULL), _m_offset (-1) + : _m_base (-1), _m_begin (0), _m_end (0), _m_cu (NULL), _m_readptr ((unsigned char *)1) {} inline const_iterator (const const_iterator &i) : _m_base (i._m_base), _m_begin (i._m_begin), _m_end (i._m_end), - _m_cu (i._m_cu), _m_offset (i._m_offset) + _m_cu (i._m_cu), _m_readptr (i._m_readptr) {} inline value_type operator* () const { - if (unlikely (_m_offset == 1)) + if (unlikely (_m_readptr == (unsigned char *)-1)) throw std::runtime_error ("dereferencing end iterator"); return std::make_pair (_m_base + _m_begin, _m_base + _m_end); } @@ -1353,13 +1354,13 @@ namespace elfutils _m_begin = other._m_begin; _m_end = other._m_end; _m_cu = other._m_cu; - _m_offset = other._m_offset; + _m_readptr = other._m_readptr; return *this; } inline bool operator== (const const_iterator &other) const { - return _m_offset == other._m_offset && _m_cu == other._m_cu; + return _m_readptr == other._m_readptr && _m_cu == other._m_cu; } inline bool operator!= (const const_iterator &other) const { @@ -1375,14 +1376,10 @@ namespace elfutils } }; - const_iterator begin () const - { - const_iterator it (_m_attr.thisattr (), 0); - return ++it; - } + const_iterator begin () const; const_iterator end () const { - return const_iterator (_m_attr.thisattr (), 1); + return const_iterator (-1, _m_attr.thisattr (), (unsigned char *)-1); } const_iterator find (const key_type &match) const @@ -1502,7 +1499,8 @@ namespace elfutils // For end iterator. inline explicit const_iterator (Dwarf_Attribute *attr) - : dwarf::range_list::const_iterator (attr, 1), _m_block () + : dwarf::range_list::const_iterator (-1, attr, (unsigned char *)-1) + , _m_block () {} public: diff --git a/libdw/c++/values.cc b/libdw/c++/values.cc index f255d794..7330d329 100644 --- a/libdw/c++/values.cc +++ b/libdw/c++/values.cc @@ -1,5 +1,5 @@ /* -*- C++ -*- interfaces for libdw. - Copyright (C) 2009-2010 Red Hat, Inc. + Copyright (C) 2009-2011 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -387,15 +387,33 @@ namespace elfutils // dwarf::range_list -dwarf::range_list::const_iterator::const_iterator (Dwarf_Attribute *attr, - ptrdiff_t offset) - : _m_base (-1), _m_begin (0), _m_end (0), _m_cu (attr->cu), _m_offset (offset) +unsigned char * +dwarf::range_list::const_iterator::formptr (int secndx, Dwarf_Attribute *attr) { - if (_m_offset == 0) + unsigned char *readptr = __libdw_formptr (attr, secndx, + DWARF_E_NO_DEBUG_RANGES, + NULL, NULL); + xif (attr, readptr == NULL); + return readptr; +} + +dwarf::range_list::const_iterator +dwarf::range_list::begin () const +{ + const_iterator it (IDX_debug_ranges, _m_attr.thisattr (), 0); + return ++it; +} + +dwarf::range_list::const_iterator::const_iterator (int secndx, + Dwarf_Attribute *attr, + unsigned char *readptr) + : _m_base (-1), _m_begin (0), _m_end (0), _m_cu (attr->cu) + , _m_readptr (readptr) +{ + if (_m_readptr == NULL) { - Dwarf_Word ofs; - xif (attr, dwarf_formudata (attr, &ofs) < 0); // XXX __libdw_formptr - _m_offset = ofs; + _m_readptr = formptr (secndx, attr); + xif (attr, _m_readptr == NULL); } } @@ -405,17 +423,16 @@ range_list_advance (int secndx, Dwarf_Addr &base, Dwarf_Addr &begin, Dwarf_Addr &end, - ptrdiff_t &offset, + unsigned char *&readp, unsigned char **valp) { const Elf_Data *d = cu->dbg->sectiondata[secndx]; if (unlikely (d == NULL)) throw std::runtime_error ("XXX no ranges"); - if (unlikely (offset < 0) || unlikely ((size_t) offset >= d->d_size)) - throw std::runtime_error ("XXX bad offset in ranges iterator"); + if (unlikely (readp >= (unsigned char *)d->d_buf + d->d_size)) + throw std::runtime_error ("XXX bad readptr in ranges iterator"); - unsigned char *readp = reinterpret_cast<unsigned char *> (d->d_buf) + offset; unsigned char *const readendp = reinterpret_cast<unsigned char *> (d->d_buf) + d->d_size; @@ -449,12 +466,11 @@ range_list_advance (int secndx, } if (begin == 0 && end == 0) /* End of list entry. */ - offset = 1; + readp = (unsigned char *)-1; else { if (valp) *valp = readp; - offset = readp - reinterpret_cast<unsigned char *> (d->d_buf); if (base == (Dwarf_Addr) -1) { @@ -484,7 +500,7 @@ dwarf::range_list::const_iterator & dwarf::range_list::const_iterator::operator++ () { xif (_m_cu, range_list_advance (IDX_debug_ranges, _m_cu, _m_base, - _m_begin, _m_end, _m_offset, NULL)); + _m_begin, _m_end, _m_readptr, NULL)); return *this; } @@ -582,11 +598,12 @@ inline void dwarf::location_attr::const_iterator::advance () { xif (_m_cu, range_list_advance (IDX_debug_loc, _m_cu, - _m_base, _m_begin, _m_end, _m_offset, + _m_base, _m_begin, _m_end, _m_readptr, &_m_block.data)); - if (_m_offset > 1) - _m_offset += 2 + (_m_block.length - = read_2ubyte_unaligned_inc (_m_cu->dbg, _m_block.data)); + // Special values are (unsigned char *){-1, 0, 1}. + if (((uintptr_t)_m_readptr + 1) > 2) + _m_readptr += 2 + (_m_block.length + = read_2ubyte_unaligned_inc (_m_cu->dbg, _m_block.data)); else // End iterator. _m_block = Dwarf_Block (); @@ -598,11 +615,9 @@ dwarf::location_attr::begin () const const_iterator i (_m_attr.thisattr ()); if (is_list ()) { - // XXX __libdw_formptr - Dwarf_Word offset; - xif (_m_attr.thisattr (), - dwarf_formudata (_m_attr.thisattr (), &offset) < 0); - i._m_offset = offset; + i._m_readptr = const_iterator::formptr (IDX_debug_loc, + _m_attr.thisattr ()); + xif (_m_attr.thisattr (), i._m_readptr == NULL); i.advance (); } else @@ -611,7 +626,7 @@ dwarf::location_attr::begin () const dwarf_formblock (_m_attr.thisattr (), &i._m_block) < 0); i._m_base = 0; i._m_end = -1; - i._m_offset = 0; + i._m_readptr = NULL; } return i; @@ -620,13 +635,13 @@ dwarf::location_attr::begin () const dwarf::location_attr::const_iterator & dwarf::location_attr::const_iterator::operator++ () { - if (unlikely (_m_offset == 1)) + if (unlikely (_m_readptr == (unsigned char *)-1)) throw std::runtime_error ("incrementing end iterator"); - if (_m_offset == 0) + if (_m_readptr == NULL) { // Singleton, now at end. - _m_offset = 1; + _m_readptr = (unsigned char *)-1; _m_block.data = NULL; _m_block.length = 0; } |