summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/linker/elf_builder.h45
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 {