summaryrefslogtreecommitdiff
path: root/rld-elf.cpp
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2012-11-17 17:34:33 +1100
committerChris Johns <chrisj@rtems.org>2012-11-17 17:34:33 +1100
commit7ee957ca2f579802b4823ad562f05bd27ad425e1 (patch)
tree5f085ca653f2d80496e984b978b556b561127064 /rld-elf.cpp
parentd68833ada79a4255e95017b44f73dcb21c7a7701 (diff)
Refactor the ELF support to allow ELF write suppport.
The refactoring allows better reuse of the ELF support and cleans up some hacks from the generic file and archive handling improving the separation of the file handling from the file format, ie ELF. The handling of ELF object files and ELF object files inside archives is cleaner. The refactor cleaned up the symbol handling where the symbols now reside in the ELF file object and references are take in symbol pointer containers and symbol table containers. The main purpose of the refactor is to allow support for creating and writing ELF files. Also added an rtems-syms command where special symbol support can be added.
Diffstat (limited to 'rld-elf.cpp')
-rw-r--r--rld-elf.cpp772
1 files changed, 584 insertions, 188 deletions
diff --git a/rld-elf.cpp b/rld-elf.cpp
index 8f983b6..30cd4b6 100644
--- a/rld-elf.cpp
+++ b/rld-elf.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2011, Chris Johns <chrisj@rtems.org>
+ * Copyright (c) 2011-2012, Chris Johns <chrisj@rtems.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
@@ -30,18 +30,23 @@ namespace rld
{
namespace elf
{
- void error (const std::string& where)
+ /**
+ * Throw an ELF error.
+ *
+ * @param where Where the error is raised.
+ */
+ void libelf_error (const std::string& where)
{
- throw rld::error (::elf_errmsg (-1), "elf:" + where);
+ throw rld::error (::elf_errmsg (-1), "libelf:" + where);
}
/**
* We record the first class, machine and .. type of object file we get the
* header of and all header must match. We cannot mix object module types.
*/
- static int elf_object_class = ELFCLASSNONE;
- static int elf_object_data = ELFDATANONE;
- static int elf_object_machinetype = EM_NONE;
+ static unsigned int elf_object_class = ELFCLASSNONE;
+ static unsigned int elf_object_data = ELFDATANONE;
+ static unsigned int elf_object_machinetype = EM_NONE;
/**
* A single place to initialise the libelf library. This must be called
@@ -54,255 +59,656 @@ namespace rld
if (!libelf_initialised)
{
if (::elf_version (EV_CURRENT) == EV_NONE)
- error ("initialisation");
+ libelf_error ("initialisation");
libelf_initialised = true;
}
}
- /**
- * Return the RTEMS target type given the ELF machine type.
- */
- const std::string
- machine_type ()
+ section::section (file& file_, int index_)
+ : file_ (&file_),
+ index_ (index_),
+ scn (0),
+ data_ (0)
{
- struct types_and_labels
- {
- const char* name; //< The RTEMS label.
- int machinetype; //< The machine type.
- };
- types_and_labels types_to_labels[] =
- {
- { "arm", EM_ARM },
- { "avr", EM_AVR },
- { "bfin", EM_BLACKFIN },
- { "h8300", EM_H8_300 },
- { "i386", EM_386 },
- /* { "m32c", EM_M32C }, Not in libelf I imported */
- { "m32r", EM_M32R },
- { "m68k", EM_68K },
- { "m68k", EM_COLDFIRE },
- { "mips", EM_MIPS },
- { "powerpc", EM_PPC },
- { "sh", EM_SH },
- { "sparc", EM_SPARC },
- { "sparc64", EM_SPARC },
- { 0, EM_NONE }
- };
+ memset (&shdr, 0, sizeof (shdr));
- int m = 0;
- while (types_to_labels[m].machinetype != EM_NONE)
+ scn = ::elf_getscn (file_.get_elf (), index_);
+ if (!scn)
+ libelf_error ("elf_getscn: " + file_.name ());
+
+ if (!::gelf_getshdr (scn, &shdr))
+ libelf_error ("gelf_getshdr: " + file_.name ());
+
+ if (shdr.sh_type != SHT_NULL)
{
- if (elf_object_machinetype == types_to_labels[m].machinetype)
- return types_to_labels[m].name;
- ++m;
+ name_ = file_.get_string (shdr.sh_name);
+ data_ = ::elf_getdata (scn, NULL);
+ if (!data_)
+ libelf_error ("elf_getdata: " + name_ + '(' + file_.name () + ')');
}
-
- std::ostringstream what;
- what << "unknown machine type: " << elf_object_machinetype;
- throw rld::error (what, "machine-type");
}
- section::section (int index,
- std::string& name,
- elf_scn* scn,
- elf_shdr& shdr)
- : index (index),
- name (name),
- scn (scn),
- shdr (shdr)
+ section::section (const section& orig)
+ : file_ (orig.file_),
+ index_ (orig.index_),
+ name_ (orig.name_),
+ scn (orig.scn),
+ shdr (orig.shdr),
+ data_ (orig.data_)
{
- data = ::elf_getdata (scn, NULL);
- if (!data)
- error ("elf_getdata");
}
section::section ()
- : index (-1),
+ : file_ (0),
+ index_ (-1),
scn (0),
- data (0)
+ data_ (0)
{
memset (&shdr, 0, sizeof (shdr));
}
+ int
+ section::index () const
+ {
+ check ();
+ return index_;
+ }
+
+ const std::string&
+ section::name () const
+ {
+ check ();
+ return name_;
+ }
+
+ elf_data*
+ section::data ()
+ {
+ check ();
+ return data_;
+ }
+
+ elf_word
+ section::type () const
+ {
+ check ();
+ return shdr.sh_type;
+ }
+
+ elf_xword
+ section::flags () const
+ {
+ check ();
+ return shdr.sh_flags;
+ }
+
+ elf_addr
+ section::address () const
+ {
+ check ();
+ return shdr.sh_addr;
+ }
+
+ elf_xword
+ section::alignment () const
+ {
+ check ();
+ return shdr.sh_addralign;
+ }
+
+ elf_off
+ section::offset () const
+ {
+ check ();
+ return shdr.sh_offset;
+ }
+
+ elf_word
+ section::link () const
+ {
+ check ();
+ return shdr.sh_link;
+ }
+
+ elf_word
+ section::info () const
+ {
+ check ();
+ return shdr.sh_info;
+ }
+
+ elf_xword
+ section::size () const
+ {
+ check ();
+ return shdr.sh_size;
+ }
+
+ elf_xword
+ section::entry_size () const
+ {
+ check ();
+ return shdr.sh_entsize;
+ }
+
+ int
+ section::entries () const
+ {
+ return size () / entry_size ();
+ }
+
+ void
+ section::check () const
+ {
+ if (!file_ || (index_ < 0))
+ throw rld::error ("Invalid section.", "section:check:");
+ }
+
+ file::file ()
+ : fd_ (-1),
+ archive (false),
+ writable (false),
+ elf_ (0),
+ oclass (0),
+ ident_str (0),
+ ident_size (0)
+ {
+ memset (&ehdr, 0, sizeof (ehdr));
+ memset (&phdr, 0, sizeof (phdr));
+ }
+
+ file::~file ()
+ {
+ end ();
+ }
+
+ void
+ file::begin (const std::string& name__, int fd__, const bool writable_)
+ {
+ begin (name__, fd__, writable_, 0, 0);
+ }
+
+ void
+ file::begin (const std::string& name__, file& archive_, off_t offset)
+ {
+ archive_.check ("begin:archive");
+
+ if (archive_.writable)
+ throw rld::error ("archive is writable", "elf:file:begin");
+
+ begin (name__, archive_.fd_, false, &archive_, offset);
+ }
+
#define rld_archive_fhdr_size (60)
void
- begin (rld::files::image& image)
+ file::begin (const std::string& name__,
+ int fd__,
+ const bool writable_,
+ file* archive_,
+ off_t offset_)
{
- libelf_initialise ();
+ if (fd__ < 0)
+ throw rld::error ("no file descriptor", "elf:file:begin");
/*
* Begin's are not nesting.
*/
- Elf* elf = image.elf ();
- if (elf)
- error ("begin: already done: " + image.name ().full ());
+ if (elf_ || (fd_ >= 0))
+ throw rld::error ("already called", "elf:file:begin");
/*
- * Is this image part of an archive ?
+ * Cannot write directly into archive. Create a file then archive it.
*/
- elf = image.elf (true);
- if (elf)
- {
- ssize_t offset = image.name ().offset () - rld_archive_fhdr_size;
+ if (archive_ && writable_)
+ throw rld::error ("cannot write into archives directly",
+ "elf:file:begin");
- if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
- std::cout << "elf::rand: " << elf << " offset:" << offset
- << ' ' << image.name ().full () << std::endl;
+ libelf_initialise ();
- if (::elf_rand (elf, offset) != offset)
- error ("begin:" + image.name ().full ());
+ /*
+ * Is this image part of an archive ?
+ */
+ if (archive_)
+ {
+ ssize_t offset = offset_ - rld_archive_fhdr_size;
+ if (::elf_rand (archive_->elf_, offset) != offset)
+ libelf_error ("rand: " + archive_->name_);
}
/*
* Note, the elf passed is either the archive or NULL.
*/
- elf = ::elf_begin (image.fd (), ELF_C_READ, elf);
- if (!elf)
- error ("begin:" + image.name ().full ());
+ elf* elf__ = ::elf_begin (fd__,
+ writable_ ? ELF_C_WRITE : ELF_C_READ,
+ archive_ ? archive_->elf_ : 0);
+ if (!elf__)
+ libelf_error ("begin: " + name__);
if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
- std::cout << "elf::begin: " << elf
- << ' ' << image.name ().full () << std::endl;
+ std::cout << "elf::begin: " << elf__ << ' ' << name__ << std::endl;
- image.set_elf (elf);
+ elf_kind ek = ::elf_kind (elf__);
- elf_kind ek = ::elf_kind (elf);
- if (image.name ().is_archive ())
+ /*
+ * If this is inside an archive it must be an ELF file.
+ */
+
+ if (archive_ && (ek != ELF_K_ELF))
+ throw rld::error ("File format in archive not ELF", "elf:file:begin: " + name__);
+ else
{
- if (ek != ELF_K_AR)
- throw rld::error ("File not an ar archive", "libelf:" + image.name ().full ());
+ if (ek == ELF_K_AR)
+ archive = true;
+ else if (ek == ELF_K_ELF)
+ archive = false;
+ else
+ throw rld::error ("File format not ELF or archive",
+ "elf:file:begin: " + name__);
}
- else if (ek != ELF_K_ELF)
- throw rld::error ("File format not ELF", "libelf:" + image.name ().full ());
- /*
- * If an ELF file make sure they all match. On the first file that begins
- * an ELF session record its settings.
- */
- if (ek == ELF_K_ELF)
+ if (!writable_)
{
- int cl = ::gelf_getclass (elf);
-
- if (elf_object_class == ELFCLASSNONE)
- elf_object_class = cl;
- else if (cl != elf_object_class)
- throw rld::error ("Mixed classes not allowed (32bit/64bit).",
- "begin:" + image.name ().full ());
-
- char* ident = elf_getident (elf, NULL);
-
- if (elf_object_data == ELFDATANONE)
- elf_object_data = ident[EI_DATA];
- else if (elf_object_data != ident[EI_DATA])
- throw rld::error ("Mixed data types not allowed (LSB/MSB).",
- "begin:" + image.name ().full ());
+ /*
+ * If an ELF file make sure they all match. On the first file that
+ * begins an ELF session record its settings.
+ */
+ if (ek == ELF_K_ELF)
+ {
+ oclass = ::gelf_getclass (elf__);
+ ident_str = elf_getident (elf__, &ident_size);
+ }
}
+
+ fd_ = fd__;
+ name_ = name__;
+ writable = writable_;
+ elf_ = elf__;
+
+ if (!archive)
+ load_header ();
}
void
- end (rld::files::image& image)
+ file::end ()
{
- ::Elf* elf = image.elf ();
- if (elf)
+ if (elf_)
{
if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
- std::cout << "elf::end: " << elf
- << ' ' << image.name ().full () << std::endl;
- ::elf_end (elf);
+ std::cout << "libelf::end: " << elf_
+ << ' ' << name_ << std::endl;
+ ::elf_end (elf_);
}
- image.set_elf (0);
+
+ fd_ = -1;
+ name_.clear ();
+ archive = false;
+ elf_ = 0;
+ oclass = 0;
+ ident_str = 0;
+ ident_size = 0;
+ memset (&ehdr, 0, sizeof (ehdr));
+ memset (&phdr, 0, sizeof (phdr));
+ stab.clear ();
+ secs.clear ();
}
void
- get_header (rld::files::image& image, elf_ehdr& ehdr)
+ file::load_header ()
{
- if (::gelf_getehdr (image.elf (), &ehdr) == NULL)
- error ("get-header:" + image.name ().full ());
-
- if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_REL))
- throw rld::error ("Invalid ELF type (only ET_EXEC/ET_REL supported).",
- "get-header:" + image.name ().full ());
+ check ("get_header");
- if (elf_object_machinetype == EM_NONE)
- elf_object_machinetype = ehdr.e_machine;
- else if (elf_object_machinetype != ehdr.e_machine)
+ if (::gelf_getehdr (elf_, &ehdr) == NULL)
+ error ("get-header");
+ }
+
+ unsigned int
+ file::machinetype () const
+ {
+ check ("machinetype");
+ return ehdr.e_machine;
+ }
+
+ unsigned int
+ file::type () const
+ {
+ check ("type");
+ return ehdr.e_type;
+ }
+
+ unsigned int
+ file::object_class () const
+ {
+ check ("object_class");
+ return oclass;
+ }
+
+ unsigned int
+ file::data_type () const
+ {
+ check ("data_type");
+ if (!ident_str)
+ throw rld::error ("No ELF ident str", "elf:file:data_type: " + name_);
+ return ident_str[EI_DATA];
+ }
+
+ bool
+ file::is_archive () const
+ {
+ check ("is_archive");
+ return archive;
+ }
+
+ bool
+ file::is_executable () const
+ {
+ check ("is_executable");
+ return ehdr.e_type != ET_REL;
+ }
+
+ bool
+ file::is_relocatable() const
+ {
+ check ("is_relocatable");
+ return ehdr.e_type == ET_REL;
+ }
+
+ int
+ file::section_count () const
+ {
+ check ("section_count");
+ return ehdr.e_shnum;
+ }
+
+ void
+ file::load_sections ()
+ {
+ if (secs.empty ())
{
- std::ostringstream oss;
- oss << "get-header:" << image.name ().full ()
- << ": " << elf_object_machinetype << '/' << ehdr.e_machine;
- throw rld::error ("Mixed machine types not supported.", oss.str ());
+ check ("load_sections_headers");
+ for (int sn = 0; sn < section_count (); ++sn)
+ secs.push_back (section (*this, sn));
}
}
void
- get_section_headers (rld::files::object& object,
- sections& secs,
- unsigned int type)
+ file::get_sections (sections& filtered_secs, unsigned int type)
{
- for (int sn = 0; sn < object.sections (); ++sn)
+ load_sections ();
+ filtered_secs.clear ();
+ for (sections::iterator si = secs.begin ();
+ si != secs.end ();
+ ++si)
{
- ::Elf_Scn* scn = ::elf_getscn (object.elf (), sn);
- if (!scn)
- error ("elf_getscn:" + object.name ().full ());
- ::GElf_Shdr shdr;
- if (!::gelf_getshdr (scn, &shdr))
- error ("gelf_getshdr:" + object.name ().full ());
- if (shdr.sh_type == type)
- {
- std::string name = get_string (object,
- object.section_strings (),
- shdr.sh_name);
- secs.push_back (section (sn, name, scn, shdr));
- }
+ if ((type == 0) || ((*si).type () == type))
+ filtered_secs.push_back (*si);
}
}
void
- load_symbol_table (rld::symbols::table& exported,
- rld::files::object& object,
- section& sec,
- bool local,
- bool weak,
- bool global)
- {
- int count = sec.shdr.sh_size / sec.shdr.sh_entsize;
- for (int s = 0; s < count; ++s)
+ file::load_symbols ()
+ {
+ if (symbols.empty ())
{
- GElf_Sym esym;
- if (!::gelf_getsym (sec.data, s, &esym))
- error ("gelf_getsym");
- std::string name = get_string (object, sec.shdr.sh_link, esym.st_name);
- if (!name.empty ())
+ sections symbol_secs;
+
+ get_sections (symbol_secs, SHT_SYMTAB);
+
+ for (sections::iterator si = symbol_secs.begin ();
+ si != symbol_secs.end ();
+ ++si)
{
- int stype = GELF_ST_TYPE (esym.st_info);
- int sbind = GELF_ST_BIND (esym.st_info);
- if (rld::verbose () >= RLD_VERBOSE_TRACE)
- {
- rld::symbols::symbol sym (name, esym);
- std::cout << "elf::symbol: ";
- sym.output (std::cout);
- std::cout << std::endl;
- }
- if ((stype == STT_NOTYPE) && (esym.st_shndx == SHN_UNDEF))
- object.unresolved_symbols ()[name] = rld::symbols::symbol (name, esym);
- else if (((stype == STT_NOTYPE) ||
- (stype == STT_OBJECT) ||
- (stype == STT_FUNC)) &&
- ((local && (sbind == STB_LOCAL)) ||
- (weak && (sbind == STB_WEAK)) ||
- (global && (sbind == STB_GLOBAL))))
+ section& sec = *si;
+ int syms = sec.entries ();
+
+ for (int s = 0; s < syms; ++s)
{
- exported[name] = rld::symbols::symbol (name, object, esym);;
- object.external_symbols ().push_back (&exported[name]);
+ elf_sym esym;
+
+ if (!::gelf_getsym (sec.data (), s, &esym))
+ error ("gelf_getsym");
+
+ std::string name = get_string (sec.link (), esym.st_name);
+
+ if (!name.empty ())
+ {
+ symbols::symbol sym (name, esym);
+
+ if (rld::verbose () >= RLD_VERBOSE_TRACE)
+ {
+ std::cout << "elf::symbol: ";
+ sym.output (std::cout);
+ std::cout << std::endl;
+ }
+
+ symbols.push_back (sym);
+ }
}
}
}
}
void
+ file::get_symbols (symbols::pointers& filtered_syms,
+ bool unresolved,
+ bool local,
+ bool weak,
+ bool global)
+ {
+ if (rld::verbose () >= RLD_VERBOSE_DETAILS)
+ std::cout << "elf:get-syms: unresolved:" << unresolved
+ << " local:" << local
+ << " weak:" << weak
+ << " global:" << global
+ << " " << name_
+ << std::endl;
+
+ load_symbols ();
+
+ filtered_syms.clear ();
+
+ for (symbols::bucket::iterator si = symbols.begin ();
+ si != symbols.end ();
+ ++si)
+ {
+ symbols::symbol& sym = *si;
+
+ int stype = sym.type ();
+ int sbind = sym.binding ();
+
+ /*
+ * If wanting unresolved symbols and the type is no-type and the
+ * section is undefined, or, the type is no-type or object or function
+ * and the bind is local and we want local symbols, or the bind is weak
+ * and we want weak symbols, or the bind is global and we want global
+ * symbols then add the filtered symbols container.
+ */
+ bool add = false;
+
+ if ((stype == STT_NOTYPE) && (sym.index () == SHN_UNDEF))
+ {
+ if (unresolved)
+ add = true;
+ }
+ else if (!unresolved)
+ {
+ if (((stype == STT_NOTYPE) ||
+ (stype == STT_OBJECT) ||
+ (stype == STT_FUNC)) &&
+ ((local && (sbind == STB_LOCAL)) ||
+ (weak && (sbind == STB_WEAK)) ||
+ (global && (sbind == STB_GLOBAL))))
+ add = true;
+ }
+
+ if (add)
+ filtered_syms.push_back (&sym);
+ }
+ }
+
+ int
+ file::strings_section () const
+ {
+ check ("strings_sections");
+ return ehdr.e_shstrndx;
+ }
+
+ std::string
+ file::get_string (int section, size_t offset)
+ {
+ check ("get_string");
+ char* s = ::elf_strptr (elf_, section, offset);
+ if (!s)
+ error ("elf_strptr");
+ return s;
+ }
+
+ std::string
+ file::get_string (size_t offset)
+ {
+ check ("get_string");
+ char* s = ::elf_strptr (elf_, strings_section (), offset);
+ if (!s)
+ error ("elf_strptr");
+ return s;
+ }
+
+#if 0
+ void
+ file::set_header (xxx)
+ {
+ elf_ehdr* ehdr_ = ::gelf_newehdr (elf_);
+
+ if (ehdr == NULL)
+ error ("set-header");
+
+ ehdr->xx = xx;
+
+ ::gelf_flagphdr (elf_, ELF_C_SET , ELF_F_DIRTY);
+ }
+#endif
+
+ elf*
+ file::get_elf ()
+ {
+ return elf_;
+ }
+
+ const std::string&
+ file::name () const
+ {
+ return name_;
+ }
+
+ bool
+ file::is_writable () const
+ {
+ return writable;
+ }
+
+ void
+ file::check (const char* where) const
+ {
+ if (!elf_ || (fd_ < 0))
+ {
+ std::string w = where;
+ throw rld::error ("no elf file or header", "elf:file:" + w);
+ }
+ }
+
+ void
+ file::check_writable (const char* where) const
+ {
+ check (where);
+ if (!writable)
+ {
+ std::string w = where;
+ throw rld::error ("not writable", "elf:file:" + w);
+ }
+ }
+
+ void
+ file::error (const char* where) const
+ {
+ std::string w = where;
+ libelf_error (w + ": " + name_);
+ }
+
+ const std::string
+ machine_type (unsigned int machinetype)
+ {
+ struct types_and_labels
+ {
+ const char* name; //< The RTEMS label.
+ unsigned int machinetype; //< The machine type.
+ };
+ types_and_labels types_to_labels[] =
+ {
+ { "arm", EM_ARM },
+ { "avr", EM_AVR },
+ { "bfin", EM_BLACKFIN },
+ { "h8300", EM_H8_300 },
+ { "i386", EM_386 },
+ /* { "m32c", EM_M32C }, Not in libelf I imported */
+ { "m32r", EM_M32R },
+ { "m68k", EM_68K },
+ { "m68k", EM_COLDFIRE },
+ { "mips", EM_MIPS },
+ { "powerpc", EM_PPC },
+ { "sh", EM_SH },
+ { "sparc", EM_SPARC },
+ { "sparc64", EM_SPARC },
+ { 0, EM_NONE }
+ };
+
+ int m = 0;
+ while (types_to_labels[m].machinetype != EM_NONE)
+ {
+ if (machinetype == types_to_labels[m].machinetype)
+ return types_to_labels[m].name;
+ ++m;
+ }
+
+ std::ostringstream what;
+ what << "unknown machine type: " << elf_object_machinetype;
+ throw rld::error (what, "machine-type");
+ }
+
+ const std::string machine_type ()
+ {
+ return machine_type (elf_object_machinetype);
+ }
+
+ void
+ check_file(const file& file)
+ {
+ if (elf_object_machinetype == EM_NONE)
+ elf_object_machinetype = file.machinetype ();
+ else if (file.machinetype () != elf_object_machinetype)
+ {
+ std::ostringstream oss;
+ oss << "elf:check_file:" << file.name ()
+ << ": " << elf_object_machinetype << '/' << file.machinetype ();
+ throw rld::error ("Mixed machine types not supported.", oss.str ());
+ }
+
+ if (elf_object_class == ELFCLASSNONE)
+ elf_object_class = file.object_class ();
+ else if (file.object_class () != elf_object_class)
+ throw rld::error ("Mixed classes not allowed (32bit/64bit).",
+ "elf:check_file: " + file.name ());
+
+ if (elf_object_data == ELFDATANONE)
+ elf_object_data = file.data_type ();
+ else if (elf_object_data != file.data_type ())
+ throw rld::error ("Mixed data types not allowed (LSB/MSB).",
+ "elf:check_file: " + file.name ());
+ }
+
+#if 0
+ void
load_symbols (rld::symbols::table& symbols,
- rld::files::object& object,
+ rld::files::object& object,
bool local,
bool weak,
bool global)
@@ -314,17 +720,7 @@ namespace rld
++si)
load_symbol_table (symbols, object, *si, local, weak, global);
}
-
- std::string
- get_string (rld::files::object& object,
- int section,
- size_t offset)
- {
- char* s = ::elf_strptr (object.elf (), section, offset);
- if (!s)
- error ("elf_strptr");
- return s;
- }
+#endif
}
}