return ebl_strtabadd (_m_strtab, str, 0);
}
+ Ebl_Strent *add (std::string const &str)
+ {
+ return ebl_strtabadd (_m_strtab, str.c_str (), str.length () + 1);
+ }
+
private:
Ebl_Strtab *_m_strtab;
};
throw std::logic_error ("copying dwarf_output requires a collector");
}
+ public:
+
+ class gap
+ {
+ unsigned char *_m_ptr;
+ size_t _m_len;
+
+ public:
+ gap (section_appender &appender, size_t len)
+ : _m_ptr (appender.alloc (len)), _m_len (len)
+ {}
+ gap (unsigned char *ptr, size_t len)
+ : _m_ptr (ptr), _m_len (len)
+ {}
+ void patch (uint64_t value) const;
+ };
+
+ // [(gap, string entry)]
+ typedef std::vector<std::pair<gap, ::Ebl_Strent *> > str_backpatch_vec;
+
+ struct backpatch_strp
+ {
+ void operator () (std::pair<gap, ::Ebl_Strent *> const &v)
+ {
+ v.first.patch (ebl_strtaboffset (v.second));
+ }
+ };
+
+ private:
// die offset -> file address
typedef std::map< ::Dwarf_Off, ::Dwarf_Off> die_off_map;
- // [((pointer, length), die offset)]
- typedef std::vector<std::pair<std::pair<unsigned char *, size_t>,
- ::Dwarf_Off> > backpatch_vec;
- static void recursively_dump (section_appender &appender,
- dwarf_output_collector &c,
- debug_info_entry const &die,
- unsigned level,
- bool a_addr_64,
- die_off_map &die_off,
- backpatch_vec &backpatch);
+ // [(gap, die offset)]
+ typedef std::vector<std::pair<gap, ::Dwarf_Off> > die_backpatch_vec;
+
+ class backpatch_die_ref
+ {
+ die_off_map const &die_off;
+ public:
+ backpatch_die_ref (die_off_map const &m) : die_off (m) {}
+ void operator () (std::pair<gap, ::Dwarf_Off> const &v)
+ {
+ die_off_map::const_iterator ot = die_off.find (v.second);
+ assert (ot != die_off.end ());
+ v.first.patch (ot->second);
+ }
+ };
+
+ class recursive_dumper
+ {
+ dwarf_output_collector &c;
+ section_appender &appender;
+ strtab &debug_str;
+ bool addr_64;
+ die_off_map &die_off;
+ die_backpatch_vec &die_backpatch;
+ str_backpatch_vec &str_backpatch;
+
+ recursive_dumper (recursive_dumper const ©); // nocopy
+
+ public:
+ recursive_dumper (dwarf_output_collector &a_c,
+ section_appender &a_appender,
+ strtab &a_debug_str,
+ bool a_addr_64,
+ die_off_map &a_die_off,
+ die_backpatch_vec &a_die_backpatch,
+ str_backpatch_vec &a_str_backpatch)
+ : c (a_c),
+ appender (a_appender),
+ debug_str (a_debug_str),
+ addr_64 (a_addr_64),
+ die_off (a_die_off),
+ die_backpatch (a_die_backpatch),
+ str_backpatch (a_str_backpatch)
+ {}
+
+ void dump (debug_info_entry const &die, unsigned level);
+ };
public:
// Constructor for an empty file, can add to its compile_units ().
void output_debug_info (section_appender &appender,
dwarf_output_collector &dw,
+ strtab &debug_str,
+ str_backpatch_vec &str_backpatch,
bool addr_64);
};
case dwarf::VS_string:
case dwarf::VS_identifier:
- return DW_FORM_string;
+ return DW_FORM_strp;
case dwarf::VS_constant:
if (! attr.second.constant_is_integer ())
return DW_FORM_udata;
case DW_AT_comp_dir:
- return DW_FORM_string;
+ return DW_FORM_strp;
case DW_AT_name:
switch (tag)
{
case DW_TAG_compile_unit:
case DW_TAG_partial_unit:
- return DW_FORM_string;
+ return DW_FORM_strp;
}
break;
}
}
void
-dwarf_output::recursively_dump (section_appender &appender,
- dwarf_output_collector &c,
- debug_info_entry const &die,
- unsigned level,
- bool addr_64,
- dwarf_output::die_off_map &die_off,
- dwarf_output::backpatch_vec &backpatch)
+dwarf_output::gap::patch (uint64_t value) const
+{
+ ::dw_write_var (_m_ptr, _m_len, value);
+}
+
+void
+dwarf_output::recursive_dumper::dump (debug_info_entry const &die, unsigned level)
{
static char const spaces[] =
" "
|| form == DW_FORM_string
|| form == DW_FORM_strp)
{
- assert (form == DW_FORM_string); // XXX temporary
std::string const &str =
vs == dwarf::VS_string
? value.string ()
? value.source_file ().name ()
: value.identifier ());
- std::copy (str.begin (), str.end (), inserter);
- *inserter++ = 0;
+ if (form == DW_FORM_string)
+ {
+ std::copy (str.begin (), str.end (), inserter);
+ *inserter++ = 0;
+ }
+ else
+ {
+ assert (form == DW_FORM_strp);
+
+ // xxx dwarf_64
+ str_backpatch.push_back
+ (std::make_pair (gap (appender, 4),
+ debug_str.add (str)));
+ }
}
else if (vs == dwarf::VS_source_file
&& form == DW_FORM_udata)
case dwarf::VS_reference:
{
assert (form == DW_FORM_ref_addr);
- // Emit zero, patch later.
// XXX dwarf64
- unsigned char *ptr = appender.alloc (4);
- ::dw_write<4> (ptr, 0);
- backpatch.push_back
- (std::make_pair (std::make_pair (ptr, 4),
+ die_backpatch.push_back
+ (std::make_pair (gap (appender, 4),
value.reference ()->offset ()));
}
break;
{
for (compile_unit::children_type::const_iterator jt
= die.children ().begin (); jt != die.children ().end (); ++jt)
- recursively_dump (appender, c, *jt, level + 1, addr_64,
- die_off, backpatch);
+ dump (*jt, level + 1);
*inserter++ = 0;
}
}
void
dwarf_output::output_debug_info (section_appender &appender,
dwarf_output_collector &c,
+ strtab &debug_str,
+ str_backpatch_vec &str_backpatch,
bool addr_64)
{
/* We request appender directly, because we depend on .alloc method
*inserter++ = addr_64 ? 8 : 4;
die_off_map die_off;
- backpatch_vec backpatch;
+ die_backpatch_vec die_backpatch;
//std::cout << "UNIT " << it->_m_cu_die << std::endl;
- recursively_dump (appender, c, *it->_m_cu_die, 0, addr_64,
- die_off, backpatch);
+ recursive_dumper (c, appender, debug_str, addr_64,
+ die_off, die_backpatch, str_backpatch)
+ .dump (*it->_m_cu_die, 0);
- /* Do the back-patching. */
- for (backpatch_vec::const_iterator bt = backpatch.begin ();
- bt != backpatch.end (); ++bt)
- {
- die_off_map::const_iterator ot = die_off.find (bt->second);
- assert (ot != die_off.end ());
- ::dw_write_var (bt->first.first, bt->first.second, ot->second);
- }
+ std::for_each (die_backpatch.begin (), die_backpatch.end (),
+ backpatch_die_ref (die_off));
/* Back-patch length. */
size_t length = appender.size () - cu_start - 4; // -4 for length info. XXX dwarf64
strings_LDADD = $(libelf) $(libeu) $(libmudflap)
ar_LDADD = libar.a $(libelf) $(libeu) $(libmudflap)
unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(libmudflap) -ldl
-dwarfcmp_LDADD = $(libdwpp) $(libmudflap) -ldl
+dwarfcmp_LDADD = $(libdwpp) $(libmudflap) $(libebl) -ldl
writer_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) $(libdwpp) -ldl
dwarflint_LDADD = $(libebl) $(libelf) $(libdwpp) $(libeu) $(libmudflap) -ldl
bool addr_64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64;
elfutils::strtab debug_strtab (false);
+ elfutils::dwarf_output::str_backpatch_vec str_backpatch;
for (size_t i = 0; debug_sections[i] != NULL; ++i)
{
if (i == si_abbrev)
dwout.output_debug_abbrev (appender, collector, addr_64);
else if (i == si_info)
- dwout.output_debug_info (appender, collector, addr_64);
+ dwout.output_debug_info (appender, collector,
+ debug_strtab, str_backpatch,
+ addr_64);
// xxx
/* We have to set the section size. */
data_info.shdr.sh_size = debug_strtab.finalize (data_info.newscn)->d_size;
shdr_info.push_back (data_info);
+
+ std::for_each (str_backpatch.begin (), str_backpatch.end (),
+ elfutils::dwarf_output::backpatch_strp ());
}
// .shstrtab
libdwpp = ../libdw/libdwpp.a $(libdw)
dwarf_print_SOURCES = dwarf-print.cc ../src/dwarfstrings.c
-dwarf_print_LDADD = $(libdwpp) $(libmudflap) -ldl
+dwarf_print_LDADD = $(libdwpp) $(libmudflap) $(libebl) -ldl
dwarf_edit_SOURCES = dwarf_edit.cc ../src/dwarfstrings.c
-dwarf_edit_LDADD = $(libdwpp) $(libmudflap) -ldl
+dwarf_edit_LDADD = $(libdwpp) $(libmudflap) $(libebl) -ldl
arextract_LDADD = $(libelf) $(libmudflap)
arsymtest_LDADD = $(libelf) $(libmudflap)