summaryrefslogtreecommitdiffstats
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-10-07 16:58:54 +0000
committerRui Ueyama <ruiu@google.com>2015-10-07 16:58:54 +0000
commit0db335fd5e0cdce981815882b8e6730cafff11f0 (patch)
treedae6c053b3f7e4d4c89e0777415c68f3645e3273 /lld/ELF/OutputSections.cpp
parentd3d114ba54893ef6a03f42040ef40feb7a4a96c8 (diff)
downloadbcm5719-llvm-0db335fd5e0cdce981815882b8e6730cafff11f0.tar.gz
bcm5719-llvm-0db335fd5e0cdce981815882b8e6730cafff11f0.zip
ELF2: Move functions out of line.
llvm-svn: 249566
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r--lld/ELF/OutputSections.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index eb33444be72..636440ed352 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -203,6 +203,36 @@ template <class ELFT> void HashTableSection<ELFT>::addSymbol(SymbolBody *S) {
S->setDynamicSymbolTableIndex(Hashes.size());
}
+template <class ELFT> void HashTableSection<ELFT>::finalize() {
+ this->Header.sh_link = DynSymSec.getSectionIndex();
+
+ assert(DynSymSec.getNumSymbols() == Hashes.size() + 1);
+ unsigned NumEntries = 2; // nbucket and nchain.
+ NumEntries += DynSymSec.getNumSymbols(); // The chain entries.
+
+ // Create as many buckets as there are symbols.
+ // FIXME: This is simplistic. We can try to optimize it, but implementing
+ // support for SHT_GNU_HASH is probably even more profitable.
+ NumEntries += DynSymSec.getNumSymbols();
+ this->Header.sh_size = NumEntries * sizeof(Elf_Word);
+}
+
+template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
+ unsigned NumSymbols = DynSymSec.getNumSymbols();
+ auto *P = reinterpret_cast<Elf_Word *>(Buf);
+ *P++ = NumSymbols; // nbucket
+ *P++ = NumSymbols; // nchain
+
+ Elf_Word *Buckets = P;
+ Elf_Word *Chains = P + NumSymbols;
+
+ for (unsigned I = 1; I < NumSymbols; ++I) {
+ uint32_t Hash = Hashes[I - 1] % NumSymbols;
+ Chains[I] = Buckets[Hash];
+ Buckets[Hash] = I;
+ }
+}
+
template <class ELFT>
DynamicSection<ELFT>::DynamicSection(SymbolTable &SymTab,
HashTableSection<ELFT> &HashSec,
@@ -499,6 +529,20 @@ SymbolTableSection<ELFT>::SymbolTableSection(
Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
}
+template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
+ this->Header.sh_size = getNumSymbols() * sizeof(Elf_Sym);
+ this->Header.sh_link = StrTabSec.getSectionIndex();
+ this->Header.sh_info = NumLocals + 1;
+}
+
+template <class ELFT>
+void SymbolTableSection<ELFT>::addSymbol(StringRef Name, bool isLocal) {
+ StrTabSec.add(Name);
+ ++NumVisible;
+ if (isLocal)
+ ++NumLocals;
+}
+
template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
Buf += sizeof(Elf_Sym);
OpenPOWER on IntegriCloud