summaryrefslogtreecommitdiff
path: root/rld-rap.cpp
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2012-12-12 21:51:03 +1100
committerChris Johns <chrisj@rtems.org>2012-12-12 21:51:03 +1100
commite735d244c24b606a1d3c9a79ef731de29a7b2ef6 (patch)
treef6ba87f1f51a7255d2da20b46063ba30dab29cb5 /rld-rap.cpp
parent4c10232ae7298504c124c33a8c0dc27c86dad5b5 (diff)
Relocation fixes.
These changes implement a suitable relocation output in the image. The code is still not working 100% but these changes are a big improvement.
Diffstat (limited to 'rld-rap.cpp')
-rw-r--r--rld-rap.cpp555
1 files changed, 400 insertions, 155 deletions
diff --git a/rld-rap.cpp b/rld-rap.cpp
index 53e5172..c786db9 100644
--- a/rld-rap.cpp
+++ b/rld-rap.cpp
@@ -66,19 +66,25 @@ namespace rld
};
/**
- * RAP relocation record.
+ * RAP relocation record. This one does not have const fields.
*/
struct relocation
{
- std::string name; //< The symbol name if there is one.
- uint32_t offset; //< The offset in the section to apply the fixup.
- uint32_t info; //< The ELF info record.
- uint32_t addend; //< The ELF constant addend.
+ uint32_t offset; //< The offset in the section to apply the fixup.
+ uint32_t info; //< The ELF info record.
+ uint32_t addend; //< The ELF constant addend.
+ std::string symname; //< The symbol name if there is one.
+ uint32_t symtype; //< The type of symbol.
+ int symsect; //< The symbol's RAP section.
+ uint32_t symvalue; //< The symbol's default value.
/**
- * Construct the relocation.
+ * Construct the relocation using the file relocation, the offset of the
+ * section in the target RAP section and the RAP section of the symbol.
*/
- relocation (const files::relocation& reloc, uint32_t offset = 0);
+ relocation (const files::relocation& reloc,
+ const uint32_t offset = 0,
+ const int symsect = 0);
};
/**
@@ -87,6 +93,13 @@ namespace rld
typedef std::list < relocation > relocations;
/**
+ * Map of object file section offsets keyed by the object file section
+ * index. This is used when adding the external symbols so the symbol's
+ * value can be adjusted by the offset of the section in the RAP section.
+ */
+ typedef std::map < int, uint32_t > osections;
+
+ /**
* The RAP section data.
*/
struct section
@@ -97,6 +110,7 @@ namespace rld
uint32_t align; //< The alignment of the section.
bool rela; //< The relocation record has an addend field.
relocations relocs; //< The relocations for this section.
+ osections osecs; //< The object section index.
/**
* Operator to add up section data.
@@ -182,12 +196,6 @@ namespace rld
files::sections symtab; //< All exported symbols.
files::sections strtab; //< All exported strings.
section secs[rap_secs]; //< The sections of interest.
- uint32_t symtab_off; //< The symbols section file offset.
- uint32_t symtab_size; //< The symbols section size.
- uint32_t strtab_off; //< The strings section file offset.
- uint32_t strtab_size; //< The strings section size.
- uint32_t relocs_off; //< The reloc's section file offset.
- uint32_t relocs_size; //< The reloc's section size.
/**
* The constructor. Need to have an object file to create.
@@ -204,6 +212,17 @@ namespace rld
*/
sections find (const uint32_t index) const;
+ /**
+ * The total number of relocations in the object file.
+ */
+ uint32_t get_relocations () const;
+
+ /**
+ * The total number of relocations for a specific RAP section in the
+ * object file.
+ */
+ uint32_t get_relocations (int sec) const;
+
private:
/**
* No default constructor allowed.
@@ -239,7 +258,7 @@ namespace rld
*
* @param obj The object file to collection the symbol from.
*/
- void collect_symbols (const object& obj);
+ void collect_symbols (object& obj);
/**
* Write the compressed output file.
@@ -265,17 +284,63 @@ namespace rld
*/
void write_relocations (compress::compressor& comp);
+ /**
+ * The total number of relocations for a specific RAP section in the
+ * image.
+ */
+ uint32_t get_relocations (int sec) const;
+
+ /**
+ * Clear the image values.
+ */
+ void clear ();
+
+ /**
+ * Update the section values.
+ *
+ * @param index The RAP section index to update.
+ * @param sec The object's RAP section.
+ */
+ void update_section (int index, const section& sec);
+
private:
- objects objs; //< The RAP objects
- section secs[rap_secs]; //< The sections of interest.
- externals externs; //< The symbols in the image
- uint32_t symtab_size; //< The size of the symbols.
- std::string strtab; //< The strings table.
- uint32_t relocs_size; //< The relocations size.
+ objects objs; //< The RAP objects
+ uint32_t sec_size[rap_secs]; //< The sections of interest.
+ uint32_t sec_align[rap_secs]; //< The sections of interest.
+ bool sec_rela[rap_secs]; //< The sections of interest.
+ externals externs; //< The symbols in the image
+ uint32_t symtab_size; //< The size of the symbols.
+ std::string strtab; //< The strings table.
+ uint32_t relocs_size; //< The relocations size.
};
/**
+ * Update the offset taking into account the alignment.
+ *
+ * @param offset The current offset.
+ * @param size The size to move the offset by.
+ * @param alignment The alignment of the offset.
+ * @return uint32_t The new aligned offset.
+ */
+ uint32_t align_offset (uint32_t offset, uint32_t size, uint32_t alignment)
+ {
+ offset += size;
+
+ if (alignment > 1)
+ {
+ uint32_t mask = alignment - 1;
+ if (offset & mask)
+ {
+ offset &= ~mask;
+ offset += alignment;
+ }
+ }
+
+ return offset;
+ }
+
+ /**
* Output helper function to report the sections in an object file.
* This is useful when seeing the flags in the sections.
*
@@ -329,18 +394,24 @@ namespace rld
}
}
- relocation::relocation (const files::relocation& reloc, uint32_t offset)
- : name (reloc.name),
- offset (offset + reloc.offset),
+ relocation::relocation (const files::relocation& reloc,
+ const uint32_t offset,
+ const int symsect)
+ : offset (reloc.offset + offset),
info (reloc.info),
- addend (reloc.info)
+ addend (reloc.addend),
+ symname (reloc.symname),
+ symtype (reloc.symtype),
+ symsect (symsect),
+ symvalue (reloc.symvalue)
{
}
section::section ()
: size (0),
offset (0),
- align (0)
+ align (0),
+ rela (false)
{
}
@@ -350,6 +421,7 @@ namespace rld
size = 0;
offset = 0;
align = 0;
+ rela = false;
}
section&
@@ -370,6 +442,8 @@ namespace rld
size += sec.size;
}
+ rela = sec.rela;
+
return *this;
}
@@ -386,25 +460,7 @@ namespace rld
void
section::set_offset (const section& sec)
{
- offset = sec.offset + sec.size;
-
- if (align > 1)
- {
- uint32_t mask = align - 1;
- if (offset & mask)
- {
- offset &= ~mask;
- offset += align;
- }
- }
-
- for (relocations::iterator ri = relocs.begin ();
- ri != relocs.end ();
- ++ri)
- {
- relocation& reloc = *ri;
- reloc.offset += offset;
- }
+ offset = align_offset (sec.offset, sec.size, align);
}
void
@@ -418,36 +474,86 @@ namespace rld
}
/**
- * Helper for for_each to get the relocations.
+ * Helper for for_each to merge the related object sections into the RAP
+ * section.
*/
- class section_relocs:
+ class section_merge:
public std::unary_function < const files::section, void >
{
public:
- section_relocs (section& sec);
+ section_merge (object& obj, section& sec);
void operator () (const files::section& fsec);
private:
+ object& obj;
section& sec;
};
- section_relocs::section_relocs (section& sec)
- : sec (sec)
+ section_merge::section_merge (object& obj, section& sec)
+ : obj (obj),
+ sec (sec)
{
+ sec.align = 0;
+ sec.offset = 0;
+ sec.size = 0;
+ sec.rela = false;
}
void
- section_relocs::operator () (const files::section& fsec)
+ section_merge::operator () (const files::section& fsec)
{
- for (files::relocations::const_iterator ri = fsec.relocs.begin ();
- ri != fsec.relocs.end ();
- ++ri)
+ if (sec.align == 0)
+ sec.align = fsec.alignment;
+ else if (sec.align != fsec.alignment)
+ throw rld::error ("Alignments do not match for section '" + sec.name + "'",
+ "rap::section");
+
+ uint32_t offset = align_offset (sec.size, 0, sec.align);
+
+ if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+ std::cout << "rap:section-merge: relocs=" << fsec.relocs.size ()
+ << " offset=" << offset
+ << " fsec.name=" << fsec.name
+ << " fsec.size=" << fsec.size
+ << " fsec.alignment=" << fsec.alignment
+ << " " << obj.obj.name ().full () << std::endl;
+
+ /*
+ * Add the object file's section offset to the map. This is needed
+ * to adjust the external symbol offsets.
+ */
+ sec.osecs[fsec.index] = offset;
+
+ uint32_t rc = 0;
+
+ for (files::relocations::const_iterator fri = fsec.relocs.begin ();
+ fri != fsec.relocs.end ();
+ ++fri, ++rc)
{
- sec.relocs.push_back (relocation (*ri, sec.offset));
+ const files::relocation& freloc = *fri;
+
+ if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+ std::cout << " " << std::setw (2) << sec.relocs.size ()
+ << '/' << std::setw (2) << rc
+ << std::hex << ": reloc.info=0x" << freloc.info << std::dec
+ << " reloc.offset=" << freloc.offset
+ << " reloc.addend=" << freloc.addend
+ << " reloc.symtype=" << freloc.symtype
+ << std::endl;
+
+ if (freloc.symtype == STT_NOTYPE)
+ sec.relocs.push_back (relocation (freloc, offset));
+ else
+ sec.relocs.push_back (relocation (freloc,
+ offset,
+ obj.find (freloc.symsect)));
}
+
+ sec.rela = fsec.rela;
+ sec.size = offset + fsec.size;
}
external::external (const uint32_t name,
@@ -470,13 +576,7 @@ namespace rld
}
object::object (files::object& obj)
- : obj (obj),
- symtab_off (0),
- symtab_size (0),
- strtab_off (0),
- strtab_size (0),
- relocs_off (0),
- relocs_size (0)
+ : obj (obj)
{
/*
* Set up the names of the sections.
@@ -485,8 +585,9 @@ namespace rld
secs[s].name = section_names[s];
/*
- * Get the relocation records. Setting the offset will update them.
- * section.
+ * Get the relocation records. Collect the various section types from the
+ * object file into the RAP sections. Merge those sections into the RAP
+ * sections.
*/
obj.open ();
@@ -495,18 +596,14 @@ namespace rld
obj.begin ();
obj.load_relocations ();
obj.end ();
- obj.close ();
}
catch (...)
{
obj.close ();
throw;
}
+ obj.close ();
- /*
- * Get from the object file the various sections we need to format a
- * memory layout.
- */
obj.get_sections (text, SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
obj.get_sections (const_, SHT_PROGBITS, SHF_ALLOC | SHF_MERGE, SHF_WRITE | SHF_EXECINSTR);
obj.get_sections (ctor, ".ctors");
@@ -516,33 +613,20 @@ namespace rld
obj.get_sections (symtab, SHT_SYMTAB);
obj.get_sections (strtab, ".strtab");
- secs[rap_text].update (text);
- secs[rap_const].update (const_);
- secs[rap_ctor].update (ctor);
- secs[rap_dtor].update (dtor);
- secs[rap_data].update (data);
- secs[rap_bss].update (bss);
-
std::for_each (text.begin (), text.end (),
- section_relocs (secs[rap_text]));
+ section_merge (*this, secs[rap_text]));
std::for_each (const_.begin (), const_.end (),
- section_relocs (secs[rap_const]));
+ section_merge (*this, secs[rap_const]));
std::for_each (ctor.begin (), ctor.end (),
- section_relocs (secs[rap_ctor]));
+ section_merge (*this, secs[rap_ctor]));
std::for_each (dtor.begin (), dtor.end (),
- section_relocs (secs[rap_dtor]));
+ section_merge (*this, secs[rap_dtor]));
std::for_each (data.begin (), data.end (),
- section_relocs (secs[rap_data]));
+ section_merge (*this, secs[rap_data]));
std::for_each (bss.begin (), bss.end (),
- section_relocs (secs[rap_bss]));
-
- symtab_size = files::sum_sizes (symtab);
- strtab_size = files::sum_sizes (strtab);
- relocs_size = 0;
- for (int s = 0; s < rap_secs; ++s)
- relocs_size += secs[s].relocs.size ();
+ section_merge (*this, secs[rap_bss]));
- if (rld::verbose () >= RLD_VERBOSE_TRACE)
+ if (1 || rld::verbose () >= RLD_VERBOSE_TRACE)
{
std::cout << "rap:object: " << obj.name ().full () << std::endl;
output ("text", secs[rap_text].size, text);
@@ -552,10 +636,6 @@ namespace rld
output ("data", secs[rap_data].size, data);
if (secs[rap_bss].size)
std::cout << " bss: size: " << secs[rap_bss].size << std::endl;
- output ("symtab", symtab_size, symtab);
- output ("strtab", strtab_size, strtab);
- if (relocs_size)
- std::cout << " relocs: size: " << relocs_size << std::endl;
}
}
@@ -568,13 +648,7 @@ namespace rld
data (orig.data),
bss (orig.bss),
symtab (orig.symtab),
- strtab (orig.strtab),
- symtab_off (orig.symtab_off),
- symtab_size (orig.symtab_size),
- strtab_off (orig.strtab_off),
- strtab_size (orig.strtab_size),
- relocs_off (orig.relocs_off),
- relocs_size (orig.relocs_size)
+ strtab (orig.strtab)
{
for (int s = 0; s < rap_secs; ++s)
secs[s] = orig.secs[s];
@@ -613,20 +687,34 @@ namespace rld
"' not found: " + obj.name ().full (), "rap::object");
}
- image::image ()
- : symtab_size (0),
- relocs_size (0)
+ uint32_t
+ object::get_relocations () const
{
- /*
- * Set up the names of the sections.
- */
+ uint32_t relocs = 0;
for (int s = 0; s < rap_secs; ++s)
- secs[s].name = section_names[s];
+ relocs += secs[s].relocs.size ();
+ return relocs;
+ }
+
+ uint32_t
+ object::get_relocations (int sec) const
+ {
+ if ((sec < 0) || (sec >= rap_secs))
+ throw rld::error ("Invalid section index '" + rld::to_string (index),
+ "rap::relocations");
+ return secs[sec].relocs.size ();
+ }
+
+ image::image ()
+ {
+ clear ();
}
void
image::layout (const files::object_list& app_objects)
{
+ clear ();
+
/*
* Create the local objects which contain the layout information.
*/
@@ -643,12 +731,6 @@ namespace rld
objs.push_back (object (app_obj));
}
- for (int s = 0; s < rap_secs; ++s)
- secs[s].clear ();
-
- symtab_size = 0;
- strtab.clear ();
-
for (objects::iterator oi = objs.begin (), poi = objs.begin ();
oi != objs.end ();
++oi)
@@ -663,35 +745,32 @@ namespace rld
if (oi != objs.begin ())
{
object& pobj = *poi;
- for (int s = 1; s < rap_secs; ++s)
+ for (int s = 0; s < rap_secs; ++s)
obj.secs[s].set_offset (pobj.secs[s]);
++poi;
}
for (int s = 0; s < rap_secs; ++s)
- secs[s] += obj.secs[s];
+ update_section (s, obj.secs[s]);
collect_symbols (obj);
- relocs_size += obj.relocs_size;
+ relocs_size += obj.get_relocations ();
}
- for (int s = 1; s < rap_secs; ++s)
- secs[s].set_offset (secs[s - 1]);
-
if (1 || rld::verbose () >= RLD_VERBOSE_INFO)
{
- uint32_t total = (secs[rap_text].size + secs[rap_data].size +
- secs[rap_data].size + secs[rap_bss].size +
+ uint32_t total = (sec_size[rap_text] + sec_size[rap_data] +
+ sec_size[rap_data] + sec_size[rap_bss] +
symtab_size + strtab.size() + relocs_size);
std::cout << "rap::layout: total:" << total
- << " text:" << secs[rap_text].size << " (" << secs[rap_text].offset
- << ") const:" << secs[rap_const].size << " (" << secs[rap_const].offset
- << ") ctor:" << secs[rap_ctor].size << " (" << secs[rap_ctor].offset
- << ") dtor:" << secs[rap_dtor].size << " (" << secs[rap_dtor].offset
- << ") data:" << secs[rap_data].size << " (" << secs[rap_data].offset
- << ") bss:" << secs[rap_bss].size << " (" << secs[rap_bss].offset
- << ") symbols:" << symtab_size << " (" << externs.size () << ')'
+ << " text:" << sec_size[rap_text]
+ << " const:" << sec_size[rap_const]
+ << " ctor:" << sec_size[rap_ctor]
+ << " dtor:" << sec_size[rap_dtor]
+ << " data:" << sec_size[rap_data]
+ << " bss:" << sec_size[rap_bss]
+ << " symbols:" << symtab_size << " (" << externs.size () << ')'
<< " strings:" << strtab.size ()
<< " relocs:" << relocs_size
<< std::endl;
@@ -699,7 +778,7 @@ namespace rld
}
void
- image::collect_symbols (const object& obj)
+ image::collect_symbols (object& obj)
{
symbols::pointers& esyms = obj.obj.external_symbols ();
for (symbols::pointers::const_iterator ei = esyms.begin ();
@@ -712,10 +791,21 @@ namespace rld
{
if ((sym.binding () == STB_GLOBAL) || (sym.binding () == STB_WEAK))
{
+ int symsec = sym.section_index ();
+ sections rap_sec = obj.find (symsec);
+ section& sec = obj.secs[rap_sec];
+
+ /*
+ * The '+ 2' is for the end of string nul and the delimiting nul.
+ *
+ * The symbol's value is the symbols value plus the offset of the
+ * object file's section offset in the RAP section.
+ */
externs.push_back (external (strtab.size () + 2,
- obj.find (sym.section_index ()),
- sym.value (),
+ rap_sec,
+ sec.osecs[symsec] + sym.value (),
sym.info ()));
+
symtab_size += external::rap_size;
strtab += sym.name ();
strtab += '\0';
@@ -757,6 +847,9 @@ namespace rld
void
section_writer::operator () (object& obj)
{
+ if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+ std::cout << "rap:writing: " << section_names[sec] << std::endl;
+
switch (sec)
{
case rap_text:
@@ -809,9 +902,8 @@ namespace rld
<< (uint32_t) 0;
for (int s = 0; s < rap_secs; ++s)
- comp << secs[s].size
- << secs[s].align
- << secs[s].offset;
+ comp << sec_size[s]
+ << sec_align[s];
/*
* Output the sections from each object file.
@@ -839,19 +931,46 @@ namespace rld
files::object& obj,
const files::sections& secs)
{
+ uint32_t offset = 0;
+ uint32_t size = 0;
+
obj.open ();
try
{
obj.begin ();
+
+ if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+ std::cout << "rap:write sections: " << obj.name ().full () << std::endl;
+
for (files::sections::const_iterator si = secs.begin ();
si != secs.end ();
++si)
{
const files::section& sec = *si;
+ uint32_t unaligned_offset = offset + size;
+
+ offset = align_offset (offset, size, sec.alignment);
+
+ if (offset != unaligned_offset)
+ {
+ char ee = '\xee';
+ for (uint32_t p = 0; p < (offset - unaligned_offset); ++p)
+ comp.write (&ee, 1);
+ }
+
comp.write (obj, sec.offset, sec.size);
+
+ if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+ std::cout << " offset=" << offset
+ << " padding=" << (offset - unaligned_offset) << std::endl;
+
+ size = sec.size;
}
+ if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+ std::cout << " -- size=" << offset << std::endl;
+
obj.end ();
}
catch (...)
@@ -880,44 +999,170 @@ namespace rld
void
image::write_relocations (compress::compressor& comp)
{
- for (objects::iterator oi = objs.begin ();
- oi != objs.end ();
- ++oi)
+ for (int s = 0; s < rap_secs; ++s)
{
- object& obj = *oi;
- for (int s = 0; s < rap_secs; ++s)
+ uint32_t count = get_relocations (s);
+ uint32_t sr = 0;
+ uint32_t header;
+
+ if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+ std::cout << "rep:relocation: section:" << section_names[s]
+ << " relocs=" << count
+ << std::endl;
+
+ header = count;
+ header |= sec_rela[s] ? (1UL << 31) : 0;
+
+ comp << header;
+
+ for (objects::iterator oi = objs.begin ();
+ oi != objs.end ();
+ ++oi)
{
+ object& obj = *oi;
section& sec = obj.secs[s];
relocations& relocs = sec.relocs;
- uint32_t header = relocs.size ();
-
- header |= sec.rela ? (1 << 31) : 0;
+ uint32_t rc = 0;
- comp << header;
+ if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+ std::cout << " relocs=" << sec.relocs.size ()
+ << " sec.offset=" << sec.offset
+ << " sec.size=" << sec.size
+ << " sec.align=" << sec.align
+ << " " << obj.obj.name ().full () << std::endl;
for (relocations::const_iterator ri = relocs.begin ();
ri != relocs.end ();
- ++ri)
+ ++ri, ++sr, ++rc)
{
const relocation& reloc = *ri;
- std::size_t size = strtab.find (reloc.name);
uint32_t info = GELF_R_TYPE (reloc.info);
-
- if (size)
- info |= size << 8;
+ uint32_t offset;
+ uint32_t addend = reloc.addend;
+ bool write_addend = sec.rela;
+ bool write_symname = false;
+
+ offset = sec.offset + reloc.offset;
+
+ if (reloc.symtype == STT_SECTION)
+ {
+ /*
+ * Bit 31 clear, bits 30:8 RAP section index.
+ */
+ info |= reloc.symsect << 8;
+
+ addend += obj.secs[reloc.symsect].offset + reloc.symvalue;
+
+ write_addend = true;
+
+ if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+ std::cout << " " << std::setw (2) << sr << '/' << std::setw (2) << rc
+ <<": rsym: sect=" << section_names[reloc.symsect]
+ << " sec.offset=" << obj.secs[reloc.symsect].offset
+ << " reloc.symsect=" << reloc.symsect
+ << " reloc.symvalue=" << reloc.symvalue
+ << " reloc.addend=" << reloc.addend
+ << " addend=" << addend
+ << std::endl;
+ }
else
- info |= (1 << 31) | (reloc.name.size () << 8);
+ {
+ /*
+ * Bit 31 must be set. Bit 30 determines the type of string and
+ * bits 29:8 the strtab offset or the size of the appended
+ * string.
+ */
+
+ info |= 1 << 31;
+
+ std::size_t size = strtab.find (reloc.symname);
+
+ if (size == std::string::npos)
+ {
+ /*
+ * Bit 30 clear, the size of the symbol name.
+ */
+ info |= reloc.symname.size () << 8;
+ write_symname = true;
+ }
+ else
+ {
+ /*
+ * Bit 30 set, the offset in the strtab.
+ */
+ info |= (1 << 30) | (size << 8);
+ }
+ }
+
+ if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+ {
+ std::cout << " " << std::setw (2) << sr << '/'
+ << std::setw (2) << rc
+ << std::hex << ": reloc: info=0x" << info << std::dec
+ << " offset=" << offset;
+ if (write_addend)
+ std::cout << " addend=" << addend;
+ if (write_symname)
+ std::cout << " symname=" << reloc.symname;
+ std::cout << std::hex
+ << " reloc.info=0x" << reloc.info << std::dec
+ << " reloc.offset=" << reloc.offset
+ << " reloc.symtype=" << reloc.symtype
+ << std::endl;
+ }
+
+ comp << info << offset;
+
+ if (write_addend)
+ comp << addend;
+
+ if (write_symname)
+ comp << reloc.symname;
+ }
+ }
+ }
+ }
- comp << info << reloc.offset;
+ uint32_t
+ image::get_relocations (int sec) const
+ {
+ if ((sec < 0) || (sec >= rap_secs))
+ throw rld::error ("Invalid section index '" + rld::to_string (index),
+ "rap::image::relocations");
- if (sec.rela)
- comp << reloc.addend;
+ uint32_t relocs = 0;
- if (!size)
- comp << reloc.name;
- }
- }
+ for (objects::const_iterator oi = objs.begin ();
+ oi != objs.end ();
+ ++oi)
+ {
+ const object& obj = *oi;
+ relocs += obj.get_relocations (sec);
+ }
+
+ return relocs;
+ }
+
+ void
+ image::clear ()
+ {
+ for (int s = 0; s < rap_secs; ++s)
+ {
+ sec_size[s] = 0;
+ sec_align[s] = 0;
+ sec_rela[s] = false;
}
+ symtab_size = 0;
+ strtab.clear ();
+ relocs_size = 0;
+ }
+
+ void
+ image::update_section (int index, const section& sec)
+ {
+ sec_size[index] += sec.size;
+ sec_align[index] = sec.align;
+ sec_rela[index] = sec.rela;
}
void