summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdw/c++/dwarf28
-rw-r--r--libdw/c++/values.cc71
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;
}