diff options
Diffstat (limited to 'compiler/elf_builder.h')
-rw-r--r-- | compiler/elf_builder.h | 121 |
1 files changed, 70 insertions, 51 deletions
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h index 323c933ab..b67dd26f7 100644 --- a/compiler/elf_builder.h +++ b/compiler/elf_builder.h @@ -26,11 +26,14 @@ namespace art { -template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr> +template <typename ElfTypes> class ElfSectionBuilder : public ValueObject { public: + using Elf_Word = typename ElfTypes::Word; + using Elf_Shdr = typename ElfTypes::Shdr; + ElfSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags, - const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *link, Elf_Word info, + const ElfSectionBuilder<ElfTypes> *link, Elf_Word info, Elf_Word align, Elf_Word entsize) : section_index_(0), name_(sec_name), link_(link) { memset(§ion_, 0, sizeof(section_)); @@ -75,9 +78,14 @@ class ElfSectionBuilder : public ValueObject { const ElfSectionBuilder* const link_; }; -template <typename Elf_Word, typename Elf_Sword, typename Elf_Dyn, typename Elf_Shdr> -class ElfDynamicBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> { +template <typename ElfTypes> +class ElfDynamicBuilder FINAL : public ElfSectionBuilder<ElfTypes> { public: + using Elf_Word = typename ElfTypes::Word; + using Elf_Sword = typename ElfTypes::Sword; + using Elf_Shdr = typename ElfTypes::Shdr; + using Elf_Dyn = typename ElfTypes::Dyn; + void AddDynamicTag(Elf_Sword tag, Elf_Word d_un) { if (tag == DT_NULL) { return; @@ -86,7 +94,7 @@ class ElfDynamicBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, El } void AddDynamicTag(Elf_Sword tag, Elf_Word d_un, - const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section) { + const ElfSectionBuilder<ElfTypes>* section) { if (tag == DT_NULL) { return; } @@ -94,9 +102,9 @@ class ElfDynamicBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, El } ElfDynamicBuilder(const std::string& sec_name, - ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *link) - : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, SHT_DYNAMIC, SHF_ALLOC | SHF_ALLOC, - link, 0, kPageSize, sizeof(Elf_Dyn)) {} + ElfSectionBuilder<ElfTypes> *link) + : ElfSectionBuilder<ElfTypes>(sec_name, SHT_DYNAMIC, SHF_ALLOC | SHF_ALLOC, + link, 0, kPageSize, sizeof(Elf_Dyn)) {} ~ElfDynamicBuilder() {} Elf_Word GetSize() const { @@ -129,21 +137,22 @@ class ElfDynamicBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, El private: struct ElfDynamicState { - const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_; + const ElfSectionBuilder<ElfTypes>* section_; Elf_Sword tag_; Elf_Word off_; }; std::vector<ElfDynamicState> dynamics_; }; -template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr> -class ElfRawSectionBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> { +template <typename ElfTypes> +class ElfRawSectionBuilder FINAL : public ElfSectionBuilder<ElfTypes> { public: + using Elf_Word = typename ElfTypes::Word; + ElfRawSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags, - const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* link, Elf_Word info, + const ElfSectionBuilder<ElfTypes>* link, Elf_Word info, Elf_Word align, Elf_Word entsize) - : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, type, flags, link, info, align, - entsize) { + : ElfSectionBuilder<ElfTypes>(sec_name, type, flags, link, info, align, entsize) { } ElfRawSectionBuilder(const ElfRawSectionBuilder&) = default; @@ -161,13 +170,14 @@ class ElfRawSectionBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, std::vector<uint8_t> buf_; }; -template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr> -class ElfOatSectionBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> { +template <typename ElfTypes> +class ElfOatSectionBuilder FINAL : public ElfSectionBuilder<ElfTypes> { public: + using Elf_Word = typename ElfTypes::Word; + ElfOatSectionBuilder(const std::string& sec_name, Elf_Word size, Elf_Word offset, Elf_Word type, Elf_Word flags) - : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, type, flags, nullptr, 0, kPageSize, - 0), + : ElfSectionBuilder<ElfTypes>(sec_name, type, flags, nullptr, 0, kPageSize, 0), offset_(offset), size_(size) { } @@ -206,14 +216,17 @@ static inline unsigned elfhash(const char *_name) { return h; } -template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, - typename Elf_Shdr> -class ElfSymtabBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> { +template <typename ElfTypes> +class ElfSymtabBuilder FINAL : public ElfSectionBuilder<ElfTypes> { public: + using Elf_Addr = typename ElfTypes::Addr; + using Elf_Word = typename ElfTypes::Word; + using Elf_Sym = typename ElfTypes::Sym; + // 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<Elf_Word, Elf_Sword, Elf_Shdr>* section, + const ElfSectionBuilder<ElfTypes>* section, Elf_Addr addr, bool is_relative, Elf_Word size, @@ -228,14 +241,14 @@ class ElfSymtabBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf ElfSymtabBuilder(const std::string& sec_name, Elf_Word type, const std::string& str_name, Elf_Word str_type, bool alloc) - : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(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), - nullptr, 0, 1, 1) { + : ElfSectionBuilder<ElfTypes>(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), + nullptr, 0, 1, 1) { } ~ElfSymtabBuilder() {} @@ -365,14 +378,14 @@ class ElfSymtabBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf return symbols_.size() + 1; } - ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* GetStrTab() { + ElfSectionBuilder<ElfTypes>* GetStrTab() { return &strtab_; } private: struct ElfSymbolState { const std::string name_; - const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_; + const ElfSectionBuilder<ElfTypes>* section_; Elf_Addr addr_; Elf_Word size_; bool is_relative_; @@ -387,7 +400,7 @@ class ElfSymtabBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf Elf_Word str_type_; // The symbols in the same order they will be in the symbol table. std::vector<ElfSymbolState> symbols_; - ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> strtab_; + ElfSectionBuilder<ElfTypes> strtab_; }; template <typename Elf_Word> @@ -529,10 +542,18 @@ static inline constexpr Elf_Word NextOffset(const Elf_Shdr& cur, const Elf_Shdr& return RoundUp(prev.sh_size + prev.sh_offset, cur.sh_addralign); } -template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, typename Elf_Dyn, - typename Elf_Sym, typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr> +template <typename ElfTypes> class ElfBuilder FINAL { public: + using Elf_Addr = typename ElfTypes::Addr; + using Elf_Word = typename ElfTypes::Word; + using Elf_Sword = typename ElfTypes::Sword; + using Elf_Ehdr = typename ElfTypes::Ehdr; + using Elf_Shdr = typename ElfTypes::Shdr; + using Elf_Sym = typename ElfTypes::Sym; + using Elf_Phdr = typename ElfTypes::Phdr; + using Elf_Dyn = typename ElfTypes::Dyn; + ElfBuilder(CodeOutput* oat_writer, File* elf_file, InstructionSet isa, @@ -565,11 +586,11 @@ class ElfBuilder FINAL { } ~ElfBuilder() {} - const ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>& GetTextBuilder() const { + const ElfOatSectionBuilder<ElfTypes>& GetTextBuilder() const { return text_builder_; } - ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* GetSymtabBuilder() { + ElfSymtabBuilder<ElfTypes>* GetSymtabBuilder() { return &symtab_builder_; } @@ -1181,12 +1202,11 @@ class ElfBuilder FINAL { } // Adds the given raw section to the builder. It does not take ownership. - void RegisterRawSection(ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* bld) { + void RegisterRawSection(ElfRawSectionBuilder<ElfTypes>* bld) { other_builders_.push_back(bld); } - const ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* - FindRawSection(const char* name) { + const ElfRawSectionBuilder<ElfTypes>* FindRawSection(const char* name) { for (const auto* other_builder : other_builders_) { if (other_builder->GetName() == name) { return other_builder; @@ -1304,8 +1324,7 @@ class ElfBuilder FINAL { } } - void AssignSectionStr(ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* builder, - std::string* strtab) { + void AssignSectionStr(ElfSectionBuilder<ElfTypes>* builder, std::string* strtab) { builder->GetSection()->sh_name = strtab->size(); *strtab += builder->GetName(); *strtab += '\0'; @@ -1363,15 +1382,15 @@ class ElfBuilder FINAL { std::vector<const Elf_Shdr*> section_ptrs_; std::vector<Elf_Word> hash_; - ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> text_builder_; - ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> rodata_builder_; - ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> bss_builder_; - ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr> dynsym_builder_; - ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr> symtab_builder_; - ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> hash_builder_; - ElfDynamicBuilder<Elf_Word, Elf_Sword, Elf_Dyn, Elf_Shdr> dynamic_builder_; - ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> shstrtab_builder_; - std::vector<ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>*> other_builders_; + ElfOatSectionBuilder<ElfTypes> text_builder_; + ElfOatSectionBuilder<ElfTypes> rodata_builder_; + ElfOatSectionBuilder<ElfTypes> bss_builder_; + ElfSymtabBuilder<ElfTypes> dynsym_builder_; + ElfSymtabBuilder<ElfTypes> symtab_builder_; + ElfSectionBuilder<ElfTypes> hash_builder_; + ElfDynamicBuilder<ElfTypes> dynamic_builder_; + ElfSectionBuilder<ElfTypes> shstrtab_builder_; + std::vector<ElfRawSectionBuilder<ElfTypes>*> other_builders_; DISALLOW_COPY_AND_ASSIGN(ElfBuilder); }; |