diff options
author | Andreas Gampe <agampe@google.com> | 2014-09-04 21:47:42 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-09-05 21:54:26 -0700 |
commit | 54fc26c7350beb782d042ba61cb06284b3a367e4 (patch) | |
tree | 210758446cb200d1497172e7664152db16118348 /compiler/elf_writer_quick.h | |
parent | ed20a4d80bcd8d47b5bcdd51ef17c786c0e5015c (diff) | |
download | art-54fc26c7350beb782d042ba61cb06284b3a367e4.zip art-54fc26c7350beb782d042ba61cb06284b3a367e4.tar.gz art-54fc26c7350beb782d042ba61cb06284b3a367e4.tar.bz2 |
ART: Refactor elf_writer_quick, add symbolizer
Refactors some classes in elf_writer_quick.h to elf_builder.h to
be more friendly for re-use. Use this in oatdump to add a symtab
to an oat file.
Bug: 17187621, 17322125
Change-Id: I2333291334fd98bd09cc5717fb83cb18efe3a029
Diffstat (limited to 'compiler/elf_writer_quick.h')
-rw-r--r-- | compiler/elf_writer_quick.h | 295 |
1 files changed, 0 insertions, 295 deletions
diff --git a/compiler/elf_writer_quick.h b/compiler/elf_writer_quick.h index 890528e..4990ed0 100644 --- a/compiler/elf_writer_quick.h +++ b/compiler/elf_writer_quick.h @@ -19,7 +19,6 @@ #include "elf_utils.h" #include "elf_writer.h" -#include "instruction_set.h" namespace art { @@ -50,300 +49,6 @@ class ElfWriterQuick FINAL : public ElfWriter { : ElfWriter(driver, elf_file) {} ~ElfWriterQuick() {} - class ElfBuilder; - void WriteDebugSymbols(ElfBuilder* builder, OatWriter* oat_writer); - void ReservePatchSpace(std::vector<uint8_t>* buffer, bool debug); - - class ElfSectionBuilder { - public: - ElfSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags, - const ElfSectionBuilder *link, Elf_Word info, Elf_Word align, - Elf_Word entsize) - : name_(sec_name), link_(link) { - memset(§ion_, 0, sizeof(section_)); - section_.sh_type = type; - section_.sh_flags = flags; - section_.sh_info = info; - section_.sh_addralign = align; - section_.sh_entsize = entsize; - } - - virtual ~ElfSectionBuilder() {} - - Elf_Shdr section_; - Elf_Word section_index_ = 0; - - protected: - const std::string name_; - const ElfSectionBuilder* link_; - - Elf_Word GetLink() { - return (link_) ? link_->section_index_ : 0; - } - - private: - friend class ElfBuilder; - }; - - class ElfDynamicBuilder : public ElfSectionBuilder { - public: - void AddDynamicTag(Elf_Sword tag, Elf_Word d_un); - void AddDynamicTag(Elf_Sword tag, Elf_Word offset, ElfSectionBuilder* section); - - ElfDynamicBuilder(const std::string& sec_name, ElfSectionBuilder *link) - : ElfSectionBuilder(sec_name, SHT_DYNAMIC, SHF_ALLOC | SHF_ALLOC, link, - 0, kPageSize, sizeof(Elf_Dyn)) {} - ~ElfDynamicBuilder() {} - - protected: - struct ElfDynamicState { - ElfSectionBuilder* section_; - Elf_Sword tag_; - Elf_Word off_; - }; - std::vector<ElfDynamicState> dynamics_; - Elf_Word GetSize() { - // Add 1 for the DT_NULL, 1 for DT_STRSZ, and 1 for DT_SONAME. All of - // these must be added when we actually put the file together because - // their values are very dependent on state. - return dynamics_.size() + 3; - } - - // Create the actual dynamic vector. strsz should be the size of the .dynstr - // table and soname_off should be the offset of the soname in .dynstr. - // Since niether can be found prior to final layout we will wait until here - // to add them. - std::vector<Elf_Dyn> GetDynamics(Elf_Word strsz, Elf_Word soname_off); - - private: - friend class ElfBuilder; - }; - - class ElfRawSectionBuilder : public ElfSectionBuilder { - public: - ElfRawSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags, - const ElfSectionBuilder* link, Elf_Word info, Elf_Word align, - Elf_Word entsize) - : ElfSectionBuilder(sec_name, type, flags, link, info, align, entsize) {} - ~ElfRawSectionBuilder() {} - std::vector<uint8_t>* GetBuffer() { return &buf_; } - void SetBuffer(std::vector<uint8_t>&& buf) { buf_ = buf; } - - protected: - std::vector<uint8_t> buf_; - - private: - friend class ElfBuilder; - }; - - class ElfOatSectionBuilder : public ElfSectionBuilder { - public: - ElfOatSectionBuilder(const std::string& sec_name, Elf_Word size, Elf_Word offset, - Elf_Word type, Elf_Word flags) - : ElfSectionBuilder(sec_name, type, flags, NULL, 0, kPageSize, 0), - offset_(offset), size_(size) {} - ~ElfOatSectionBuilder() {} - - protected: - // Offset of the content within the file. - Elf_Word offset_; - // Size of the content within the file. - Elf_Word size_; - - private: - friend class ElfBuilder; - }; - - class ElfSymtabBuilder : public ElfSectionBuilder { - public: - // Add a symbol with given name to this symtab. The symbol refers to - // 'relative_addr' within the given section and has the given attributes. - void AddSymbol(const std::string& name, - const ElfSectionBuilder* section, - Elf_Addr addr, - bool is_relative, - Elf_Word size, - uint8_t binding, - uint8_t type, - uint8_t other = 0); - - ElfSymtabBuilder(const std::string& sec_name, Elf_Word type, - const std::string& str_name, Elf_Word str_type, bool alloc) - : ElfSectionBuilder(sec_name, type, ((alloc) ? SHF_ALLOC : 0U), &strtab_, 0, - sizeof(Elf_Word), sizeof(Elf_Sym)), - str_name_(str_name), str_type_(str_type), - strtab_(str_name, str_type, ((alloc) ? SHF_ALLOC : 0U), NULL, 0, 1, 1) {} - ~ElfSymtabBuilder() {} - - protected: - std::vector<Elf_Word> GenerateHashContents(); - std::string GenerateStrtab(); - std::vector<Elf_Sym> GenerateSymtab(); - - Elf_Word GetSize() { - // 1 is for the implicit NULL symbol. - return symbols_.size() + 1; - } - - struct ElfSymbolState { - const std::string name_; - const ElfSectionBuilder* section_; - Elf_Addr addr_; - Elf_Word size_; - bool is_relative_; - uint8_t info_; - uint8_t other_; - // Used during Write() to temporarially hold name index in the strtab. - Elf_Word name_idx_; - }; - - // Information for the strsym for dynstr sections. - const std::string str_name_; - Elf_Word str_type_; - // The symbols in the same order they will be in the symbol table. - std::vector<ElfSymbolState> symbols_; - ElfSectionBuilder strtab_; - - private: - friend class ElfBuilder; - }; - - class ElfBuilder FINAL { - public: - ElfBuilder(OatWriter* oat_writer, - File* elf_file, - InstructionSet isa, - Elf_Word rodata_relative_offset, - Elf_Word rodata_size, - Elf_Word text_relative_offset, - Elf_Word text_size, - const bool add_symbols, - bool debug = false) - : oat_writer_(oat_writer), - elf_file_(elf_file), - add_symbols_(add_symbols), - debug_logging_(debug), - text_builder_(".text", text_size, text_relative_offset, SHT_PROGBITS, - SHF_ALLOC | SHF_EXECINSTR), - rodata_builder_(".rodata", rodata_size, rodata_relative_offset, - SHT_PROGBITS, SHF_ALLOC), - dynsym_builder_(".dynsym", SHT_DYNSYM, ".dynstr", SHT_STRTAB, true), - symtab_builder_(".symtab", SHT_SYMTAB, ".strtab", SHT_STRTAB, false), - hash_builder_(".hash", SHT_HASH, SHF_ALLOC, &dynsym_builder_, 0, - sizeof(Elf_Word), sizeof(Elf_Word)), - dynamic_builder_(".dynamic", &dynsym_builder_), - shstrtab_builder_(".shstrtab", SHT_STRTAB, 0, NULL, 0, 1, 1) { - SetupEhdr(); - SetupDynamic(); - SetupRequiredSymbols(); - SetISA(isa); - } - ~ElfBuilder() {} - - bool Init(); - bool Write(); - - // Adds the given raw section to the builder. This will copy it. The caller - // is responsible for deallocating their copy. - void RegisterRawSection(ElfRawSectionBuilder bld) { - other_builders_.push_back(bld); - } - - private: - OatWriter* oat_writer_; - File* elf_file_; - const bool add_symbols_; - const bool debug_logging_; - - bool fatal_error_ = false; - - // What phdr is. - static const uint32_t PHDR_OFFSET = sizeof(Elf_Ehdr); - enum : uint8_t { - PH_PHDR = 0, - PH_LOAD_R__ = 1, - PH_LOAD_R_X = 2, - PH_LOAD_RW_ = 3, - PH_DYNAMIC = 4, - PH_NUM = 5, - }; - static const uint32_t PHDR_SIZE = sizeof(Elf_Phdr) * PH_NUM; - Elf_Phdr program_headers_[PH_NUM]; - - Elf_Ehdr elf_header_; - - Elf_Shdr null_hdr_; - std::string shstrtab_; - uint32_t section_index_; - std::string dynstr_; - uint32_t dynstr_soname_offset_; - std::vector<Elf_Shdr*> section_ptrs_; - std::vector<Elf_Word> hash_; - - public: - ElfOatSectionBuilder text_builder_; - ElfOatSectionBuilder rodata_builder_; - ElfSymtabBuilder dynsym_builder_; - ElfSymtabBuilder symtab_builder_; - ElfSectionBuilder hash_builder_; - ElfDynamicBuilder dynamic_builder_; - ElfSectionBuilder shstrtab_builder_; - std::vector<ElfRawSectionBuilder> other_builders_; - - private: - void SetISA(InstructionSet isa); - void SetupEhdr(); - - // Sets up a bunch of the required Dynamic Section entries. - // Namely it will initialize all the mandatory ones that it can. - // Specifically: - // DT_HASH - // DT_STRTAB - // DT_SYMTAB - // DT_SYMENT - // - // Some such as DT_SONAME, DT_STRSZ and DT_NULL will be put in later. - void SetupDynamic(); - - // Sets up the basic dynamic symbols that are needed, namely all those we - // can know already. - // - // Specifically adds: - // oatdata - // oatexec - // oatlastword - void SetupRequiredSymbols(); - void AssignSectionStr(ElfSectionBuilder *builder, std::string* strtab); - struct ElfFilePiece { - ElfFilePiece(const std::string& name, Elf_Word offset, const void* data, Elf_Word size) - : dbg_name_(name), offset_(offset), data_(data), size_(size) {} - ~ElfFilePiece() {} - - const std::string& dbg_name_; - Elf_Word offset_; - const void *data_; - Elf_Word size_; - static bool Compare(ElfFilePiece a, ElfFilePiece b) { - return a.offset_ < b.offset_; - } - }; - - // Write each of the pieces out to the file. - bool WriteOutFile(const std::vector<ElfFilePiece>& pieces); - bool IncludingDebugSymbols() { return add_symbols_ && symtab_builder_.GetSize() > 1; } - }; - - /* - * @brief Generate the DWARF debug_info and debug_abbrev sections - * @param oat_writer The Oat file Writer. - * @param dbg_info Compilation unit information. - * @param dbg_abbrev Abbreviations used to generate dbg_info. - * @param dbg_str Debug strings. - */ - void FillInCFIInformation(OatWriter* oat_writer, std::vector<uint8_t>* dbg_info, - std::vector<uint8_t>* dbg_abbrev, std::vector<uint8_t>* dbg_str, - std::vector<uint8_t>* dbg_line, uint32_t text_section_offset); - DISALLOW_IMPLICIT_CONSTRUCTORS(ElfWriterQuick); }; |