diff options
author | Chris Johns <chrisj@rtems.org> | 2012-11-20 19:53:24 +1100 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2012-11-20 19:53:24 +1100 |
commit | fd8a2c559f29dba37ff8de43ead42f89e160eaa2 (patch) | |
tree | 6a9630093755a95e4345a062be8ae85c512385ad /linkers/rld-elf.h | |
parent | 9b66527bebda528a8f65ae1376c2085fc409fe21 (diff) |
Add support to write a metadata ELF file.
This also adds support to the ELF classes that wrap libelf. While
this is now done and seems to work I will not be using an ELF
file to hold the metadata after all.
Diffstat (limited to 'linkers/rld-elf.h')
-rw-r--r-- | linkers/rld-elf.h | 243 |
1 files changed, 232 insertions, 11 deletions
diff --git a/linkers/rld-elf.h b/linkers/rld-elf.h index d9e7054..45e24fa 100644 --- a/linkers/rld-elf.h +++ b/linkers/rld-elf.h @@ -26,6 +26,7 @@ #define _RLD_ELF_H_ #include <list> +#include <map> #include <rld.h> @@ -45,10 +46,68 @@ namespace rld { public: /** - * Construct the section getting the details. + * Construct the section getting the details from the ELF file given the + * section index. * - * @param elf The ELF file this section is part of. - * @param index The sections index in the ELF file. + * The section types are (from elf(3)): + * + * Section Type Library Type Description + * ------------ ------------ ----------- + * SHT_DYNAMIC ELF_T_DYN `.dynamic' section entries. + * SHT_DYNSYM ELF_T_SYM Symbols for dynamic linking. + * SHT_FINI_ARRAY ELF_T_ADDR Termination function pointers. + * SHT_GROUP ELF_T_WORD Section group marker. + * SHT_HASH ELF_T_HASH Symbol hashes. + * SHT_INIT_ARRAY ELF_T_ADDR Initialization function pointers. + * SHT_NOBITS ELF_T_BYTE Empty sections. See elf(5). + * SHT_NOTE ELF_T_NOTE ELF note records. + * SHT_PREINIT_ARRAY ELF_T_ADDR Pre-initialization function + * pointers. + * SHT_PROGBITS ELF_T_BYTE Machine code. + * SHT_REL ELF_T_REL ELF relocation records. + * SHT_RELA ELF_T_RELA Relocation records with addends. + * SHT_STRTAB ELF_T_BYTE String tables. + * SHT_SYMTAB ELF_T_SYM Symbol tables. + * SHT_SYMTAB_SHNDX ELF_T_WORD Used with extended section + * numbering. + * SHT_GNU_verdef ELF_T_VDEF Symbol version definitions. + * SHT_GNU_verneed ELF_T_VNEED Symbol versioning requirements. + * SHT_GNU_versym ELF_T_HALF Version symbols. + * SHT_SUNW_move ELF_T_MOVE ELF move records. + * SHT_SUNW_syminfo ELF_T_SYMINFO Additional symbol flags. + * + * @param file_ The ELF file this section is part of. + * @param index_ The section's index. + * @param name The section's name. + * @param type The section's type. + * @param alignment The section's alignment. + * @param flags The section's flags. + * @param addr The section's in-memory address. + * @param offset The section's offset in the file. + * @param size The section's file in bytes. + * @param link The section's header table link. + * @param info The section's extra information. + * @param entry_size The section's entry size. + */ + section (file& file_, + int index_, + const std::string& name, + elf_word type, + elf_xword alignment, + elf_xword flags, + elf_addr addr, + elf_off offset, + elf_xword size, + elf_word link = 0, + elf_word info = 0, + elf_xword entry_size = 0); + + /** + * Construct the section given the details. The ELF file must be + * writable. + * + * @param file_ The ELF file this section is part of. + * @param index The section's index in the ELF file. */ section (file& file_, int index); @@ -63,6 +122,47 @@ namespace rld section (); /** + * Add a data segment descriptor to the section if the file is writable. + * + * These are following data types (from elf(3)): + * + * ELF_T_ADDR Machine addresses. + * ELF_T_BYTE Byte data. The library will not attempt to translate + * byte data. + * ELF_T_CAP Software and hardware capability records. + * ELF_T_DYN Records used in a section of type SHT_DYNAMIC. + * ELF_T_EHDR ELF executable header. + * ELF_T_HALF 16-bit unsigned words. + * ELF_T_LWORD 64 bit unsigned words. + * ELF_T_MOVE ELF Move records. + * ELF_T_NOTE ELF Note structures. + * ELF_T_OFF File offsets. + * ELF_T_PHDR ELF program header table entries. + * ELF_T_REL ELF relocation entries. + * ELF_T_RELA ELF relocation entries with addends. + * ELF_T_SHDR ELF section header entries. + * ELF_T_SWORD Signed 32-bit words. + * ELF_T_SXWORD Signed 64-bit words. + * ELF_T_SYMINFO ELF symbol information. + * ELF_T_SYM ELF symbol table entries. + * ELF_T_VDEF Symbol version definition records. + * ELF_T_VNEED Symbol version requirement records. + * ELF_T_WORD Unsigned 32-bit words. + * ELF_T_XWORD Unsigned 64-bit words. + * + * @param type The type of data in the segment. + * @param alignment The in-file alignment of the data. Must be a power of 2. + * @param size The number of bytes in this data descriptor. + * @param buffer The data in memory. + * @param offset The offset within the containing section. Can be computed. + */ + void add_data (elf_type type, + elf_xword alignment, + elf_xword size, + void* buffer = 0, + elf_off offset = 0); + + /** * The section's index in the ELF file. * * @return int The section number. @@ -131,12 +231,27 @@ namespace rld */ int entries () const; + /** + * Set the name index if writable. This is normally done + * automatically when adding the section to the file. + */ + void set_name (unsigned int index); + private: /** - * Check the section is acrtual valid. + * Check the section is valid. + * + * @param where Where the check is being made. + */ + void check (const char* where) const; + + /** + * Check the section is valid and writable. + * + * @param where Where the check is being made. */ - void check () const; + void check_writable (const char* where) const; file* file_; //< The ELF file. int index_; //< The section header index. @@ -147,17 +262,68 @@ namespace rld }; /** - * Container of ELF sections. + * Container of ELF section pointers. */ - typedef std::list < section > sections; + typedef std::list < section* > sections; /** + * Container of ELF section as a map, ie associative array. + */ + typedef std::map < std::string, section > section_table; + + /** + * An ELF program header. + */ + class program_header + { + public: + /** + * Construct a program header. + */ + program_header (); + + /** + * Desctruct a program header. + */ + ~program_header (); + + /** + * Set the program header. + * + * @param type The type of segment. + * @param flags The segment's flags. + * @param offset The offet to segment. + * @param filesz The segment size in the file. + * @param memsz The segment size in memory. + * @param vaddr The virtual address in memory. + * @param paddr The physical address if any. + */ + void set (elf_word type, + elf_word flags, + elf_off offset, + elf_xword filesz, + elf_xword memsz, + elf_xword align, + elf_addr vaddr, + elf_addr paddr = 0); + + private: + + elf_phdr phdr; //< The ELF program header. + }; + + /** + * A container of program headers. + */ + typedef std::list < program_header > program_headers; + + /** * An ELF file. */ class file { public: - /** + /** * Construct an ELF file. */ file (); @@ -191,6 +357,13 @@ namespace rld void end (); /** + * Write the ELF file creating it if it is writable. You should have + * added the sections and the data segment descriptors to the sections + * before calling write. + */ + void write (); + + /** * Load the header. Done automatically. */ void load_header (); @@ -300,7 +473,29 @@ namespace rld /** * Set the ELF header. Must be writable. * + * The classes are: + * ELFCLASSNONE This class is invalid. + * ELFCLASS32 This defines the 32-bit architecture. It sup- ports + * machines with files and virtual address spa- ces up to + * 4 Gigabytes. + * ELFCLASS64 This defines the 64-bit architecture. + * + * The types are: + * ET_NONE An unknown type. + * ET_REL A relocatable file. + * ET_EXEC An executable file. + * ET_DYN A shared object. + * ET_CORE A core file. + * + * The machine types are: + * TDB + * + * The datatypes are: + * ELFDATA2LSB Two's complement, little-endian. + * ELFDATA2MSB Two's complement, big-endian. + * * @param type The type of ELF file, ie executable, relocatable etc. + * @param class_ The files ELF class. * @param machinetype The type of machine code present in the ELF file. * @param datatype The data type, ie LSB or MSB. */ @@ -310,6 +505,16 @@ namespace rld unsigned char datatype); /** + * Add a section to the ELF file if writable. + */ + void add (section& sec); + + /** + * Add a program header to the ELF file if writable. + */ + void add (program_header& phdr); + + /** * Get the ELF reference. */ elf* get_elf (); @@ -387,8 +592,9 @@ namespace rld 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. + section_table secs; //< The sections as a table. + program_headers phdrs; //< The program headers when creating + // ELF files. rld::symbols::bucket symbols; //< The symbols. All tables point here. }; @@ -400,11 +606,26 @@ namespace rld const std::string machine_type (unsigned int machinetype); /** - * Return the global machine type set by the check_file call. + * Return the global machine type set by the check_file call as a string. */ const std::string machine_type (); /** + * Return the global class set by the check_file call. + */ + unsigned int object_class (); + + /** + * Return the global machine type set by the check_file call. + */ + unsigned int object_machine_type (); + + /** + * Return the global data type set by the check_file call. + */ + unsigned int object_datatype (); + + /** * 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 |