summaryrefslogtreecommitdiffstats
path: root/linkers/rld-elf.h
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
commit977c3de534bb5cce7935b47138efc2eac8e5ae23 (patch)
tree7a5625763dea69077a70265a41da4f4d6ea7eca6 /linkers/rld-elf.h
parentFix spelling. (diff)
downloadrtems-tools-977c3de534bb5cce7935b47138efc2eac8e5ae23.tar.bz2
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 'linkers/rld-elf.h')
-rw-r--r--linkers/rld-elf.h383
1 files changed, 328 insertions, 55 deletions
diff --git a/linkers/rld-elf.h b/linkers/rld-elf.h
index 763ab55..4f37636 100644
--- a/linkers/rld-elf.h
+++ b/linkers/rld-elf.h
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2011, Chris Johns <chrisj@rtems.org>
+ * Copyright (c) 2011, 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
@@ -34,87 +34,360 @@ namespace rld
namespace elf
{
/**
- * Sections.
+ * Forward decl.
*/
- struct section
+ class file;
+
+ /**
+ * An ELF Section.
+ */
+ class section
{
- int index; //< The section header index.
- std::string name; //< The section's name.
- elf_scn* scn; //< ELF private section data.
- elf_shdr shdr; //< The section header.
- elf_data* data; //< The section's data.
-
+ public:
+ /**
+ * Construct the section getting the details.
+ *
+ * @param elf The ELF file this section is part of.
+ * @param index The sections index in the ELF file.
+ */
+ section (file& file_, int index);
+
/**
- * Construct the section and get the data value.
+ * Copy constructor.
*/
- section (int index,
- std::string& name,
- elf_scn* scn,
- elf_shdr& sdhr);
+ section (const section& orig);
/**
* Default constructor.
*/
section ();
+
+ /**
+ * The section's index in the ELF file.
+ *
+ * @return int The section number.
+ */
+ int index () const;
+
+ /**
+ * The name of the section.
+ *
+ * @return const std::string& The section's name.
+ */
+ const std::string& name () const;
+
+ /**
+ * The section's data.
+ */
+ elf_data* data ();
+
+ /**
+ * Get the type of the section.
+ */
+ elf_word type () const;
+
+ /**
+ * The section flags.
+ */
+ elf_xword flags () const;
+
+ /**
+ * In-memory address of the section.
+ */
+ elf_addr address () const;
+
+ /**
+ * Alignment constraint.
+ */
+ elf_xword alignment () const;
+
+ /**
+ * The file offset of the section.
+ */
+ elf_off offset () const;
+
+ /**
+ * The header table link.
+ */
+ elf_word link () const;
+
+ /**
+ * Extra information.
+ */
+ elf_word info () const;
+
+ /**
+ * Size of the section.
+ */
+ elf_xword size () const;
+
+ /**
+ * Size of the entries in the section.
+ */
+ elf_xword entry_size () const;
+
+ /**
+ * Number of entries.
+ */
+ int entries () const;
+
+ private:
+
+ /**
+ * Check the section is acrtual valid.
+ */
+ void check () const;
+
+ file* file_; //< The ELF file.
+ int index_; //< The section header index.
+ std::string name_; //< The section's name.
+ elf_scn* scn; //< ELF private section data.
+ elf_shdr shdr; //< The section header.
+ elf_data* data_; //< The section's data.
};
/**
- * Container of section headers.
+ * Container of ELF sections.
*/
typedef std::list < section > sections;
/**
- * Get the machine type detected in the object files as their headers are read.
+ * An ELF file.
*/
- const std::string machine_type ();
+ class file
+ {
+ public:
+ /**
+ * Construct an ELF file.
+ */
+ file ();
- /**
- * Begin a libelf session with the image.
- */
- void begin (rld::files::image& image);
+ /**
+ * Destruct the ELF file object.
+ */
+ ~file ();
- /**
- * End the libelf session with the image.
- */
- void end (rld::files::image& image);
+ /**
+ * Begin using the ELF file.
+ *
+ * @param name The full name of the file.
+ * @param fd The file descriptor to read or write the file.
+ * @param writable The file is writeable. The default is false.
+ */
+ void begin (const std::string& name, int fd, const bool writable = false);
- /**
- * Get the ELF header.
- */
- void get_header (rld::files::image& image, elf_ehdr& ehdr);
+ /**
+ * Begin using the ELF file in an archive.
+ *
+ * @param name The full name of the file.
+ * @param archive The file that is the archive.
+ * @param offset The offset of the ELF file in the archive.
+ */
+ void begin (const std::string& name, file& archive, off_t offset);
+
+ /**
+ * End using the ELF file.
+ */
+ void end ();
+
+ /**
+ * Load the header. Done automatically.
+ */
+ void load_header ();
+
+ /**
+ * Get the machine type.
+ */
+ unsigned int machinetype () const;
+
+ /**
+ * Get the type of ELF file.
+ */
+ unsigned int type () const;
+
+ /**
+ * Get the class of the object file.
+ */
+ unsigned int object_class () const;
+
+ /**
+ * Get the data type, ie LSB or MSB.
+ */
+ unsigned int data_type () const;
+
+ /**
+ * Is the file an archive format file ?
+ */
+ bool is_archive () const;
+
+ /**
+ * Is the file an executable ?
+ */
+ bool is_executable () const;
+
+ /**
+ * Is the file relocatable ?
+ */
+ bool is_relocatable() const;
+
+ /**
+ * The number of sections in the file.
+ */
+ int section_count () const;
+
+ /**
+ * Load the sections.
+ */
+ void load_sections ();
+
+ /**
+ * Get a filtered container of the sections. The key is the section
+ * type. If the sections are not loaded they are loaded. If the type is 0
+ * all sections are returned.
+ *
+ * @param filtered_secs The container the copy of the filtered sections
+ * are placed in.
+ * @param type The type of sections to filter on. If 0 all sections are
+ * matched.
+ */
+ void get_sections (sections& filtered_secs, unsigned int type);
+
+ /**
+ * Return the index of the string section.
+ */
+ int strings_section () const;
+
+ /**
+ * Get the string from the specified section at the requested offset.
+ *
+ * @param section The section to search for the string.
+ * @param offset The offset in the string section.
+ * @return std::string The string.
+ */
+ std::string get_string (int section, size_t offset);
+
+ /**
+ * Get the string from the ELF header declared string section at the
+ * requested offset.
+ *
+ * @param offset The offset in the string section.
+ * @return std::string The string.
+ */
+ std::string get_string (size_t offset);
+
+ /**
+ * Load the symbols.
+ */
+ void load_symbols ();
+
+ /**
+ * Get a filtered container of symbols given the various types. If the
+ * symbols are not loaded they are loaded.
+ *
+ * @param filter_syms The filtered symbols found in the file. This is a
+ * container of pointers.
+ * @param local Return local symbols.
+ * @param weak Return weak symbols.
+ * @param global Return global symbols.
+ * @param unresolved Return unresolved symbols.
+ */
+ void get_symbols (rld::symbols::pointers& filtered_syms,
+ bool unresolved = false,
+ bool local = false,
+ bool weak = true,
+ bool global = true);
+
+ /**
+ * Get the ELF reference.
+ */
+ elf* get_elf ();
+
+ /**
+ * Get the name of the file.
+ */
+ const std::string& name () const;
+
+ /**
+ * Is the file writable ?
+ */
+ bool is_writable () const;
+
+ private:
+
+ /**
+ * Begin using the ELF file.
+ *
+ * @param name The full name of the file.
+ * @param fd The file descriptor to read or write the file.
+ * @param writable The file is writeable. It cannot be part of an archive.
+ * @param archive The archive's ELF handle or 0 if not an archive.
+ * @param offset The offset of the ELF file in the archive if elf is non-zero.
+ */
+ void begin (const std::string& name,
+ int fd,
+ const bool writable,
+ file* archive,
+ off_t offset);
+
+ /**
+ * Check if the file is usable. Throw an exception if not.
+ *
+ * @param where Where the check is performed.
+ */
+ void check (const char* where) const;
+
+ /**
+ * Check if the file is usable and writable. Throw an exception if not.
+ *
+ * @param where Where the check is performed.
+ */
+ void check_writable (const char* where) const;
+
+ /**
+ * Generate libelf error.
+ *
+ * @param where Where the error is generated.
+ */
+ void error (const char* where) const;
+
+ int fd_; //< The file handle.
+ std::string name_; //< The name of the file.
+ bool archive; //< The ELF file is part of an archive.
+ bool writable; //< The file is writeable.
+ elf* elf_; //< The ELF handle.
+ unsigned int mtype; //< The machine type.
+ unsigned int oclass; //< The object class.
+ const char* ident_str; //< The ELF file's ident string.
+ size_t ident_size; //< The size of the ident.
+ elf_ehdr ehdr; //< The ELF header.
+ elf_phdr phdr; //< The ELF program header.
+ std::string stab; //< The string table.
+ sections secs; //< The sections.
+ rld::symbols::bucket symbols; //< The symbols. All tables point here.
+ };
/**
- * Get the section headers for an object file.
- */
- void get_section_headers (rld::files::object& object,
- sections& secs,
- unsigned int type = SHT_NULL);
-
- /**
- * Load the symbol table with the symbols.
+ * Return the machine type label given the machine type.
+ *
+ * @param machinetype The ELF machine type.
*/
- void load_symbol_table (rld::symbols::table& exported,
- rld::files::object& object,
- section& sec,
- bool local = false,
- bool weak = true,
- bool global = true);
-
+ const std::string machine_type (unsigned int machinetype);
+
/**
- * Load the symbol table with an object's symbols.
+ * Return the global machine type set by the check_file call.
*/
- void load_symbols (rld::symbols::table& symbols,
- rld::files::object& object,
- bool local = false,
- bool weak = true,
- bool global = true);
+ const std::string machine_type ();
/**
- * Get a string.
+ * Check the file against the global machine type, object class and data
+ * type. If this is the first file checked it becomes the default all
+ * others are checked against. This is a simple way to make sure all files
+ * are the same type.
+ *
+ * @param file The check to check.
*/
- std::string get_string (rld::files::object& object,
- int section,
- size_t offset);
+ void check_file(const file& file);
+
}
}