summaryrefslogtreecommitdiff
path: root/rld-files.cpp
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2012-12-08 09:07:30 +1100
committerChris Johns <chrisj@rtems.org>2012-12-08 09:07:30 +1100
commit4c10232ae7298504c124c33a8c0dc27c86dad5b5 (patch)
treef2745cad4ebf5cb07111191fe6f0cd8b7dd22cd5 /rld-files.cpp
parentc6add3b2f603f4cf9be8bfe4bb4c27ccf9c086fa (diff)
Add support to demand load relocation records.
Support has been added to load relocation record on demand. The relocation records are not read when the object file is first opened and read. They are read only when being written to the output file. This save loading lots of records into memory from libraries to be thrown away. The RAP format now supports writing out relocation records.
Diffstat (limited to 'rld-files.cpp')
-rw-r--r--rld-files.cpp53
1 files changed, 49 insertions, 4 deletions
diff --git a/rld-files.cpp b/rld-files.cpp
index 94508a1..c296ab1 100644
--- a/rld-files.cpp
+++ b/rld-files.cpp
@@ -18,6 +18,8 @@
#include "config.h"
#endif
+#include <algorithm>
+
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@@ -413,7 +415,7 @@ namespace rld
size_t to_read = size;
while (have_read < size)
{
- ssize_t rsize = ::read (fd (), buffer, to_read);
+ const ssize_t rsize = ::read (fd (), buffer, to_read);
if (rsize < 0)
throw rld::error (strerror (errno), "read:" + name ().path ());
if (rsize == 0)
@@ -428,12 +430,12 @@ namespace rld
ssize_t
image::write (const void* buffer_, size_t size)
{
- const uint8_t* buffer = static_cast <const uint8_t*> (buffer_);
+ const uint8_t* buffer = static_cast <const uint8_t*> (buffer_);
size_t have_written = 0;
size_t to_write = size;
while (have_written < size)
{
- ssize_t wsize = ::write (fd (), buffer, to_write);
+ const ssize_t wsize = ::write (fd (), buffer, to_write);
if (wsize < 0)
throw rld::error (strerror (errno), "write:" + name ().path ());
have_written += wsize;
@@ -900,6 +902,15 @@ namespace rld
close ();
}
+ relocation::relocation (const elf::relocation& er)
+ : name (er.name ()),
+ offset (er.offset ()),
+ type (er.type ()),
+ info (er.info ()),
+ addend (er.addend ())
+ {
+ }
+
section::section (const elf::section& es)
: name (es.name ()),
index (es.index ()),
@@ -909,7 +920,23 @@ namespace rld
link (es.link ()),
info (es.info ()),
flags (es.flags ()),
- offset (es.offset ()){
+ offset (es.offset ()),
+ rela (es.get_reloc_type ())
+ {
+ load_relocations (es);
+ }
+
+ void
+ section::load_relocations (const elf::section& es)
+ {
+ rela = es.get_reloc_type ();
+ const elf::relocations& es_relocs = es.get_relocations ();
+ for (elf::relocations::const_iterator ri = es_relocs.begin ();
+ ri != es_relocs.end ();
+ ++ri)
+ {
+ relocs.push_back (relocation (*ri));
+ }
}
size_t
@@ -1134,6 +1161,24 @@ namespace rld
}
}
+ void
+ object::load_relocations ()
+ {
+ if (rld::verbose () >= RLD_VERBOSE_DETAILS)
+ std::cout << "object:load-relocs: " << name ().full () << std::endl;
+
+ elf ().load_relocations ();
+
+ for (sections::iterator si = secs.begin ();
+ si != secs.end ();
+ ++si)
+ {
+ section& sec = *si;
+ const elf::section& elf_sec = elf ().get_section (sec.index);
+ sec.load_relocations (elf_sec);
+ }
+ }
+
int
object::references () const
{