diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/linker/elf_builder.h | 45 |
1 files changed, 19 insertions, 26 deletions
diff --git a/compiler/linker/elf_builder.h b/compiler/linker/elf_builder.h index 81ecc175b5..44f3296e90 100644 --- a/compiler/linker/elf_builder.h +++ b/compiler/linker/elf_builder.h @@ -18,6 +18,7 @@ #define ART_COMPILER_LINKER_ELF_BUILDER_H_ #include <vector> +#include <deque> #include "arch/instruction_set.h" #include "arch/mips/instruction_set_features_mips.h" @@ -357,57 +358,49 @@ class ElfBuilder final { } // Buffer symbol for this section. It will be written later. - // If the symbol's section is null, it will be considered absolute (SHN_ABS). - // (we use this in JIT to reference code which is stored outside the debug ELF file) void Add(Elf_Word name, const Section* section, Elf_Addr addr, Elf_Word size, uint8_t binding, uint8_t type) { - Elf_Word section_index; - if (section != nullptr) { - DCHECK_LE(section->GetAddress(), addr); - DCHECK_LE(addr, section->GetAddress() + section->header_.sh_size); - section_index = section->GetSectionIndex(); - } else { - section_index = static_cast<Elf_Word>(SHN_ABS); - } - Add(name, section_index, addr, size, binding, type); - } - - // Buffer symbol for this section. It will be written later. - void Add(Elf_Word name, - Elf_Word section_index, - Elf_Addr addr, - Elf_Word size, - uint8_t binding, - uint8_t type) { Elf_Sym sym = Elf_Sym(); sym.st_name = name; sym.st_value = addr; sym.st_size = size; sym.st_other = 0; - sym.st_shndx = section_index; sym.st_info = (binding << 4) + (type & 0xf); - syms_.push_back(sym); + Add(sym, section); + } + + // Buffer symbol for this section. It will be written later. + void Add(Elf_Sym sym, const Section* section) { + DCHECK(section != nullptr); + DCHECK_LE(section->GetAddress(), sym.st_value); + DCHECK_LE(sym.st_value, section->GetAddress() + section->header_.sh_size); + sym.st_shndx = section->GetSectionIndex(); // The sh_info file must be set to index one-past the last local symbol. - if (binding == STB_LOCAL) { - this->header_.sh_info = syms_.size(); + if (sym.getBinding() == STB_LOCAL) { + DCHECK_EQ(syms_.back().getBinding(), STB_LOCAL); + this->header_.sh_info = syms_.size() + 1; } + + syms_.push_back(sym); } Elf_Word GetCacheSize() { return syms_.size() * sizeof(Elf_Sym); } void WriteCachedSection() { this->Start(); - this->WriteFully(syms_.data(), syms_.size() * sizeof(Elf_Sym)); + for (; !syms_.empty(); syms_.pop_front()) { + this->WriteFully(&syms_.front(), sizeof(Elf_Sym)); + } this->End(); } private: - std::vector<Elf_Sym> syms_; // Buffered/cached content of the whole section. + std::deque<Elf_Sym> syms_; // Buffered/cached content of the whole section. }; class AbiflagsSection final : public Section { |