struct gap
{
gap (writer &parent);
- gap (writer &parent, section_appender &appender, size_t len,
+ gap (writer &parent, section_appender &appender, int form,
uint64_t base = 0);
- gap (writer &parent, unsigned char *ptr, size_t len,
+ gap (writer &parent, unsigned char *ptr, int form,
uint64_t base = 0);
gap &operator= (gap const &other);
void patch (uint64_t value) const;
bool valid () const { return _m_ptr != NULL; }
+ void set_base (uint64_t base) { _m_base = base; }
private:
writer &_m_parent;
unsigned char *_m_ptr;
- size_t _m_len;
+ int _m_form;
uint64_t _m_base;
};
template <class Iterator>
void write_form (Iterator it, int form, uint64_t value);
- gap gap_for_form (section_appender &appender,
- int form, uint64_t base = 0);
-
/// @throws dwarf_32_not_enough
void assert_fits_32 (uint64_t value) const;
}
}
-dwarf_output::writer::gap
-dwarf_output::writer::gap_for_form (section_appender &appender,
- int form, uint64_t base)
-{
- size_t gap_size = ::form_width (form,
- _m_config.addr_64,
- _m_config.dwarf_64);
- return gap (*this, appender, gap_size, base);
-}
-
void
dwarf_output::writer::write_string (std::string const &str,
int form,
assert (form == DW_FORM_strp);
_m_str_backpatch.push_back
- (std::make_pair (gap_for_form (appender, form),
+ (std::make_pair (gap (*this, appender, form),
_m_debug_str.add (str)));
}
}
{}
dwarf_output::writer::gap::gap (writer &parent, section_appender &appender,
- size_t len, uint64_t base)
+ int form, uint64_t base)
: _m_parent (parent),
- _m_ptr (appender.alloc (len)),
- _m_len (len),
+ _m_ptr (appender.alloc (::form_width (form, parent._m_config.addr_64,
+ parent._m_config.dwarf_64))),
+ _m_form (form),
_m_base (base)
{}
dwarf_output::writer::gap::gap (writer &parent, unsigned char *ptr,
- size_t len, uint64_t base)
+ int form, uint64_t base)
: _m_parent (parent),
_m_ptr (ptr),
- _m_len (len),
+ _m_form (form),
_m_base (base)
{}
{
assert (&_m_parent == &other._m_parent);
_m_ptr = other._m_ptr;
- _m_len = other._m_len;
+ _m_form = other._m_form;
_m_base = other._m_base;
return *this;
}
void
dwarf_output::writer::gap::patch (uint64_t value) const
{
- _m_parent.write_var (_m_ptr, _m_len, value - _m_base);
+ _m_parent.write_form (_m_ptr, _m_form, value - _m_base);
}
namespace
int form = at->second;
if (attr == DW_AT_sibling)
{
- // XXX in fact we want to handle this case just like any
- // other CU-local reference. So also use this below (or
- // better reuse single piece of code for reference
- // handling).
if (debug)
std::cout << pad << " " << dwarf_attr_string (attr)
<< ":" << dwarf_form_string (form)
<< " sibling=" << info._m_with_sibling[false]
<< ":" << info._m_with_sibling[true]
<< std::endl;
- step.sibling_gap = _m_parent.gap_for_form (appender, form,
- _m_cu_start);
+ step.sibling_gap = gap (_m_parent, appender, form, _m_cu_start);
continue;
}
case dwarf::VS_lineptr:
_m_parent._m_line_backpatch.push_back
- (std::make_pair (_m_parent.gap_for_form (appender, form),
+ (std::make_pair (gap (_m_parent, appender, form),
&value.line_info ()));
break;
case dwarf::VS_source_file:
if (source_file_is_string (tag, attr))
- {
- _m_parent.write_string (value.source_file ().name (),
- form, appender);
- break;
- }
+ _m_parent.write_string (value.source_file ().name (),
+ form, appender);
else
_m_parent.write_form (inserter, form, 0 /*xxx*/);
break;
{
assert (form == DW_FORM_ref_addr);
die_backpatch.push_back
- (std::make_pair (_m_parent.gap_for_form (appender, form),
+ (std::make_pair (gap (_m_parent, appender, form),
value.reference ()->offset ()));
}
break;
{
if (_m_parent._m_config.dwarf_64)
::dw_write<4> (appender.alloc (4), -1, _m_parent._m_config.big_endian);
- // It's tempting to form the gap with a base of appender.size()+w,
- // but we need to assert_fits_32 when we finish, and thus need to
- // calculate the length ourselves.
- return _m_parent.gap_for_form (appender, DW_FORM_ref_addr);
+ gap g (_m_parent, appender, DW_FORM_ref_addr);
+ g.set_base (appender.size ());
+ return g;
}
public:
void finish ()
{
assert (!_m_finished);
- size_t length = _m_appender.size () - _m_cu_start;
- _m_parent.assert_fits_32 (length);
- _m_length_gap.patch (length);
+ _m_length_gap.patch (_m_appender.size ());
_m_finished = true;
}
};