From: Petr Machata Date: Wed, 23 Sep 2009 20:27:54 +0000 (+0200) Subject: Emit .debug_loc X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=36d85f9138e084ccc21df787572db52a203139a7;p=thirdparty%2Felfutils.git Emit .debug_loc --- diff --git a/libdw/c++/dwarf_output b/libdw/c++/dwarf_output index 906bdf293..9269060c8 100644 --- a/libdw/c++/dwarf_output +++ b/libdw/c++/dwarf_output @@ -933,6 +933,10 @@ namespace elfutils range_list const *>> range_backpatch_vec; typedef std::map range_offsets_map; + typedef std::vector> loc_backpatch_vec; + typedef std::map loc_offsets_map; + dwarf_output_collector &_m_col; dwarf_output &_m_dw; @@ -945,6 +949,9 @@ namespace elfutils range_backpatch_vec _m_range_backpatch; range_offsets_map _m_range_offsets; + loc_backpatch_vec _m_loc_backpatch; + loc_offsets_map _m_loc_offsets; + // Set of shapes. typedef std::tr1::unordered_map inserter + std::back_insert_iterator inserter = std::back_inserter (appender); for (subr::value_set::const_iterator @@ -1808,6 +1810,57 @@ dwarf_output::writer::output_debug_ranges (section_appender &appender) } } +void +dwarf_output::writer::output_debug_loc (section_appender &appender) +{ + typedef std::set loc_set; + loc_set locations; + + for (dwarf_output_collector::die_map::const_iterator it + = _m_col._m_unique.begin (); + it != _m_col._m_unique.end (); ++it) + { + debug_info_entry const &die = it->first; + for (debug_info_entry::attributes_type::const_iterator + at = die.attributes ().begin (); + at != die.attributes ().end (); ++at) + { + attr_value const &value = at->second; + dwarf::value_space vs = value.what_space (); + + if (vs == dwarf::VS_location) + { + dwarf_output::location_attr const &loc = value.location (); + locations.insert (&loc); + } + } + } + + std::back_insert_iterator inserter + = std::back_inserter (appender); + for (loc_set::const_iterator it = locations.begin (); + it != locations.end (); ++it) + { + dwarf_output::location_attr const &loc = **it; + if (!_m_loc_offsets.insert (std::make_pair (&loc, appender.size ())) + .second) + throw std::runtime_error ("duplicate loc table address"); + + for (dwarf_output::location_attr::const_iterator jt = loc.begin (); + jt != loc.end (); ++jt) + { + write_form (inserter, DW_FORM_addr, jt->first.first); + write_form (inserter, DW_FORM_addr, jt->first.second); + write_form (inserter, DW_FORM_data2, jt->second.size ()); + std::copy (jt->second.begin (), jt->second.end (), inserter); + } + + // end of list entry + write_form (inserter, DW_FORM_addr, 0); + write_form (inserter, DW_FORM_addr, 0); + } +} + void dwarf_output::writer::apply_patches () { @@ -1836,4 +1889,15 @@ dwarf_output::writer::apply_patches () throw std::runtime_error (".debug_ranges ref not found"); it->first.patch (ot->second); } + + for (loc_backpatch_vec::const_iterator it = _m_loc_backpatch.begin (); + it != _m_loc_backpatch.end (); ++it) + { + loc_offsets_map::const_iterator ot = _m_loc_offsets.find (it->second); + if (ot == _m_loc_offsets.end ()) + // no point mentioning the key, since it's just a memory + // address... + throw std::runtime_error (".debug_loc ref not found"); + it->first.patch (ot->second); + } } diff --git a/src/writer.cc b/src/writer.cc index e57c09b87..b91357629 100644 --- a/src/writer.cc +++ b/src/writer.cc @@ -586,6 +586,11 @@ handle_elf (Elf *elf, size_t alloc_unit, writer.output_debug_ranges (sec_debug_ranges); sec_debug_ranges.done (shdr_info); + new_debug_section sec_debug_loc + (".debug_loc", shst, SHT_PROGBITS, ++idx, newelf, alloc_unit); + writer.output_debug_loc (sec_debug_loc); + sec_debug_loc.done (shdr_info); + new_str_section sec_debug_str (".debug_str", shst, SHT_STRTAB, ++idx, newelf, shdr_info, debug_strtab);