summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2009-09-29 12:27:27 +0200
committerPetr Machata <pmachata@redhat.com>2009-09-29 12:27:27 +0200
commitf7a67a48e5b6107960057d0ab060d98ea9420952 (patch)
treed3a89a7f1850e8373ac0a3dceba014f443987ad1
parent58363f7493949cb8374c09c4736bb082608462df (diff)
downloadelfutils-f7a67a48e5b6107960057d0ab060d98ea9420952.tar.gz
Save non-list location values as blocks
-rw-r--r--libdw/c++/dwarf_output4
-rw-r--r--libdw/c++/output-shape.cc54
2 files changed, 43 insertions, 15 deletions
diff --git a/libdw/c++/dwarf_output b/libdw/c++/dwarf_output
index 0994d99d..ae4a0115 100644
--- a/libdw/c++/dwarf_output
+++ b/libdw/c++/dwarf_output
@@ -988,6 +988,10 @@ namespace elfutils
template <class Iterator>
void write_form (Iterator it, int form, uint64_t value);
+ template <class IteratorIn, class IteratorOut>
+ void write_block (IteratorOut it, int form,
+ IteratorIn begin, IteratorIn end);
+
/// @throws dwarf_32_not_enough
void assert_fits_32 (uint64_t value) const;
diff --git a/libdw/c++/output-shape.cc b/libdw/c++/output-shape.cc
index 41e3c9b7..a5793bb5 100644
--- a/libdw/c++/output-shape.cc
+++ b/libdw/c++/output-shape.cc
@@ -277,12 +277,8 @@ namespace
return const_forms;
case dwarf::VS_location:
- /* xxx we spit out everything in .debug_loc. Make similar
- heuristic of !is_list location as is done for strings.
-
if (!value.location ().is_list ())
return block_forms;
- */
/* Fall through. */
case dwarf::VS_lineptr:
@@ -341,9 +337,14 @@ namespace
// for much later
case dwarf::VS_discr_list:
case dwarf::VS_rangelistptr: // xxx same here
- case dwarf::VS_location: // xxx and here
return false;
+ case dwarf::VS_location:
+ if (!value.location ().is_list ())
+ return true;
+ else
+ return false; // xxx and here, too
+
case dwarf::VS_source_file:
if (source_file_is_string (tag, attr))
return true;
@@ -405,8 +406,13 @@ namespace
case dwarf::VS_reference:
case dwarf::VS_discr_list:
case dwarf::VS_lineptr:
- case dwarf::VS_location:
abort ();
+
+ case dwarf::VS_location:
+ if (!value.location ().is_list ())
+ return value.location ().location ().size ();
+ else
+ abort ();
}
abort ();
@@ -616,6 +622,20 @@ dwarf_output::writer::write_form (Iterator it, int form, uint64_t value)
+ dwarf_form_string (form));
}
+template <class IteratorIn, class IteratorOut>
+void
+dwarf_output::writer::write_block (IteratorOut it, int form,
+ IteratorIn begin, IteratorIn end)
+{
+ assert (form == DW_FORM_block
+ || form == DW_FORM_block1
+ || form == DW_FORM_block2
+ || form == DW_FORM_block4);
+
+ write_form (it, form, end - begin);
+ std::copy (begin, end, it);
+}
+
namespace
{
class CountingIterator
@@ -1235,11 +1255,9 @@ public:
if (value.constant_is_integer ())
_m_parent.write_form (inserter, form, value.constant ());
else
- {
- const std::vector<uint8_t> &block = value.constant_block ();
- _m_parent.write_form (inserter, form, block.size ());
- std::copy (block.begin (), block.end (), inserter);
- }
+ _m_parent.write_block (inserter, form,
+ value.constant_block ().begin (),
+ value.constant_block ().end ());
break;
case dwarf::VS_dwarf_constant:
@@ -1293,9 +1311,14 @@ public:
break;
case dwarf::VS_location:
- _m_parent._m_loc_backpatch.push_back
- (std::make_pair (gap (_m_parent, appender, form),
- &value.location ()));
+ if (!value.location ().is_list ())
+ _m_parent.write_block (inserter, form,
+ value.location ().location ().begin (),
+ value.location ().location ().end ());
+ else
+ _m_parent._m_loc_backpatch.push_back
+ (std::make_pair (gap (_m_parent, appender, form),
+ &value.location ()));
break;
case dwarf::VS_discr_list:
@@ -1858,7 +1881,8 @@ dwarf_output::writer::output_debug_loc (section_appender &appender)
if (vs == dwarf::VS_location)
{
dwarf_output::location_attr const &loc = value.location ();
- locations.insert (&loc);
+ if (loc.is_list ())
+ locations.insert (&loc);
}
}
}