diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-02-01 21:35:17 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-02-01 21:35:17 +0000 |
commit | 63b9abd1dbe002d940a818f51dd9d6e585e41c84 (patch) | |
tree | 8f257c7b94b6320186de5cc06685fbc0b7e0a93f | |
parent | b025d011dd270230aeb50d7174a2a05616fe81eb (diff) | |
download | src-test2-63b9abd1dbe002d940a818f51dd9d6e585e41c84.tar.gz src-test2-63b9abd1dbe002d940a818f51dd9d6e585e41c84.zip |
Notes
-rw-r--r-- | ELF/InputFiles.h | 4 | ||||
-rw-r--r-- | ELF/InputSection.cpp | 3 | ||||
-rw-r--r-- | ELF/SyntheticSections.cpp | 76 | ||||
-rw-r--r-- | ELF/SyntheticSections.h | 13 | ||||
-rw-r--r-- | ELF/Writer.cpp | 12 | ||||
-rw-r--r-- | test/ELF/Inputs/dtrace-r.o | bin | 0 -> 624 bytes | |||
-rw-r--r-- | test/ELF/aarch64-relro.s | 14 | ||||
-rw-r--r-- | test/ELF/basic-mips.s | 2 | ||||
-rw-r--r-- | test/ELF/basic-ppc.s | 2 | ||||
-rw-r--r-- | test/ELF/dtrace-r.test | 8 |
10 files changed, 83 insertions, 51 deletions
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h index 73dda7b566b8..95888061d877 100644 --- a/ELF/InputFiles.h +++ b/ELF/InputFiles.h @@ -180,10 +180,6 @@ public: // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations. uint32_t MipsGp0 = 0; - // The number is the offset in the string table. It will be used as the - // st_name of the symbol. - std::vector<std::pair<const DefinedRegular<ELFT> *, unsigned>> KeptLocalSyms; - // Name of source file obtained from STT_FILE symbol value, // or empty string if there is no such symbol in object file // symbol table. diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp index 358004248373..6b1e92891b98 100644 --- a/ELF/InputSection.cpp +++ b/ELF/InputSection.cpp @@ -246,7 +246,8 @@ void InputSection<ELFT>::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { if (Config->Rela) P->r_addend = getAddend<ELFT>(Rel); P->r_offset = RelocatedSection->getOffset(Rel.r_offset); - P->setSymbolAndType(Body.DynsymIndex, Type, Config->Mips64EL); + P->setSymbolAndType(In<ELFT>::SymTab->getSymbolIndex(&Body), Type, + Config->Mips64EL); } } diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp index f09b60b2b494..204b5993a62a 100644 --- a/ELF/SyntheticSections.cpp +++ b/ELF/SyntheticSections.cpp @@ -1065,22 +1065,21 @@ template <class ELFT> void SymbolTableSection<ELFT>::finalize() { this->OutSec->Info = this->Info = NumLocals + 1; this->OutSec->Entsize = this->Entsize; - if (Config->Relocatable) { - size_t I = NumLocals; - for (const SymbolTableEntry &S : Symbols) - S.Symbol->DynsymIndex = ++I; + if (Config->Relocatable) return; - } if (!StrTabSec.isDynamic()) { - std::stable_sort( - Symbols.begin(), Symbols.end(), - [](const SymbolTableEntry &L, const SymbolTableEntry &R) { - return L.Symbol->symbol()->computeBinding() == STB_LOCAL && - R.Symbol->symbol()->computeBinding() != STB_LOCAL; + auto GlobBegin = Symbols.begin() + NumLocals; + auto It = std::stable_partition( + GlobBegin, Symbols.end(), [](const SymbolTableEntry &S) { + return S.Symbol->symbol()->computeBinding() == STB_LOCAL; }); + // update sh_info with number of Global symbols output with computed + // binding of STB_LOCAL + this->OutSec->Info = this->Info = 1 + It - Symbols.begin(); return; } + if (In<ELFT>::GnuHashTab) // NB: It also sorts Symbols to meet the GNU hash table requirements. In<ELFT>::GnuHashTab->addSymbols(Symbols); @@ -1094,10 +1093,25 @@ template <class ELFT> void SymbolTableSection<ELFT>::finalize() { S.Symbol->DynsymIndex = ++I; } -template <class ELFT> void SymbolTableSection<ELFT>::addSymbol(SymbolBody *B) { +template <class ELFT> void SymbolTableSection<ELFT>::addGlobal(SymbolBody *B) { Symbols.push_back({B, StrTabSec.addString(B->getName(), false)}); } +template <class ELFT> void SymbolTableSection<ELFT>::addLocal(SymbolBody *B) { + assert(!StrTabSec.isDynamic()); + ++NumLocals; + Symbols.push_back({B, StrTabSec.addString(B->getName())}); +} + +template <class ELFT> +size_t SymbolTableSection<ELFT>::getSymbolIndex(SymbolBody *Body) { + auto I = llvm::find_if( + Symbols, [&](const SymbolTableEntry &E) { return E.Symbol == Body; }); + if (I == Symbols.end()) + return 0; + return I - Symbols.begin() + 1; +} + template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { Buf += sizeof(Elf_Sym); @@ -1113,26 +1127,24 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) { // Iterate over all input object files to copy their local symbols // to the output symbol table pointed by Buf. - for (ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) { - for (const std::pair<const DefinedRegular<ELFT> *, size_t> &P : - File->KeptLocalSyms) { - const DefinedRegular<ELFT> &Body = *P.first; - InputSectionBase<ELFT> *Section = Body.Section; - auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); - - if (!Section) { - ESym->st_shndx = SHN_ABS; - ESym->st_value = Body.Value; - } else { - const OutputSectionBase *OutSec = Section->OutSec; - ESym->st_shndx = OutSec->SectionIndex; - ESym->st_value = OutSec->Addr + Section->getOffset(Body); - } - ESym->st_name = P.second; - ESym->st_size = Body.template getSize<ELFT>(); - ESym->setBindingAndType(STB_LOCAL, Body.Type); - Buf += sizeof(*ESym); + + for (auto I = Symbols.begin(); I != Symbols.begin() + NumLocals; ++I) { + const DefinedRegular<ELFT> &Body = *cast<DefinedRegular<ELFT>>(I->Symbol); + InputSectionBase<ELFT> *Section = Body.Section; + auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); + + if (!Section) { + ESym->st_shndx = SHN_ABS; + ESym->st_value = Body.Value; + } else { + const OutputSectionBase *OutSec = Section->OutSec; + ESym->st_shndx = OutSec->SectionIndex; + ESym->st_value = OutSec->Addr + Section->getOffset(Body); } + ESym->st_name = I->StrTabOffset; + ESym->st_size = Body.template getSize<ELFT>(); + ESym->setBindingAndType(STB_LOCAL, Body.Type); + Buf += sizeof(*ESym); } } @@ -1141,7 +1153,9 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) { // Write the internal symbol table contents to the output symbol table // pointed by Buf. auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); - for (const SymbolTableEntry &S : Symbols) { + + for (auto I = Symbols.begin() + NumLocals; I != Symbols.end(); ++I) { + const SymbolTableEntry &S = *I; SymbolBody *Body = S.Symbol; size_t StrOff = S.StrTabOffset; diff --git a/ELF/SyntheticSections.h b/ELF/SyntheticSections.h index f7e891ec3a66..df67e079ad0e 100644 --- a/ELF/SyntheticSections.h +++ b/ELF/SyntheticSections.h @@ -366,23 +366,26 @@ public: void finalize() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override { return getNumSymbols() * sizeof(Elf_Sym); } - void addSymbol(SymbolBody *Body); + void addGlobal(SymbolBody *Body); + void addLocal(SymbolBody *Body); StringTableSection<ELFT> &getStrTabSec() const { return StrTabSec; } - unsigned getNumSymbols() const { return NumLocals + Symbols.size() + 1; } + unsigned getNumSymbols() const { return Symbols.size() + 1; } + size_t getSymbolIndex(SymbolBody *Body); ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; } static const OutputSectionBase *getOutputSection(SymbolBody *Sym); - unsigned NumLocals = 0; - StringTableSection<ELFT> &StrTabSec; - private: void writeLocalSymbols(uint8_t *&Buf); void writeGlobalSymbols(uint8_t *Buf); // A vector of symbols and their string table offsets. std::vector<SymbolTableEntry> Symbols; + + StringTableSection<ELFT> &StrTabSec; + + unsigned NumLocals = 0; }; // Outputs GNU Hash section. For detailed explanation see: diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp index 4f2f91993f8d..f00fb6d11ea5 100644 --- a/ELF/Writer.cpp +++ b/ELF/Writer.cpp @@ -455,11 +455,7 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() { InputSectionBase<ELFT> *Sec = DR->Section; if (!shouldKeepInSymtab<ELFT>(Sec, B->getName(), *B)) continue; - ++In<ELFT>::SymTab->NumLocals; - if (Config->Relocatable) - B->DynsymIndex = In<ELFT>::SymTab->NumLocals; - F->KeptLocalSyms.push_back(std::make_pair( - DR, In<ELFT>::SymTab->StrTabSec.addString(B->getName()))); + In<ELFT>::SymTab->addLocal(B); } } } @@ -1024,10 +1020,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { if (!includeInSymtab<ELFT>(*Body)) continue; if (In<ELFT>::SymTab) - In<ELFT>::SymTab->addSymbol(Body); + In<ELFT>::SymTab->addGlobal(Body); if (In<ELFT>::DynSymTab && S->includeInDynsym()) { - In<ELFT>::DynSymTab->addSymbol(Body); + In<ELFT>::DynSymTab->addGlobal(Body); if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(Body)) if (SS->file()->isNeeded()) In<ELFT>::VerNeed->addSymbol(SS); @@ -1466,7 +1462,7 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() { // The glibc dynamic loader rounds the size down, so we need to round up // to protect the last page. This is a no-op on FreeBSD which always // rounds up. - P.p_memsz = alignTo(P.p_memsz, Config->MaxPageSize); + P.p_memsz = alignTo(P.p_memsz, Target->PageSize); } // The TLS pointer goes after PT_TLS. At least glibc will align it, diff --git a/test/ELF/Inputs/dtrace-r.o b/test/ELF/Inputs/dtrace-r.o Binary files differnew file mode 100644 index 000000000000..ce742de3bd2b --- /dev/null +++ b/test/ELF/Inputs/dtrace-r.o diff --git a/test/ELF/aarch64-relro.s b/test/ELF/aarch64-relro.s new file mode 100644 index 000000000000..3ec19d73d683 --- /dev/null +++ b/test/ELF/aarch64-relro.s @@ -0,0 +1,14 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t +# RUN: ld.lld %t -o %t2 +# RUN: llvm-readobj -program-headers %t2 | FileCheck %s + +# CHECK: Type: PT_GNU_RELRO +# CHECK-NEXT: Offset: +# CHECK-NEXT: VirtualAddress: +# CHECK-NEXT: PhysicalAddress: +# CHECK-NEXT: FileSize: +# CHECK-NEXT: MemSize: 4096 + +.section .data.rel.ro,"aw",%progbits +.byte 1 diff --git a/test/ELF/basic-mips.s b/test/ELF/basic-mips.s index 67b58f8f028c..57181caf4eaf 100644 --- a/test/ELF/basic-mips.s +++ b/test/ELF/basic-mips.s @@ -176,7 +176,7 @@ __start: # CHECK-NEXT: Offset: 0x20010 # CHECK-NEXT: Size: 48 # CHECK-NEXT: Link: 10 -# CHECK-NEXT: Info: 1 +# CHECK-NEXT: Info: 2 # CHECK-NEXT: AddressAlignment: 4 # CHECK-NEXT: EntrySize: 16 # CHECK-NEXT: } diff --git a/test/ELF/basic-ppc.s b/test/ELF/basic-ppc.s index e08c7a32eb7c..aae81fe2ac0e 100644 --- a/test/ELF/basic-ppc.s +++ b/test/ELF/basic-ppc.s @@ -178,7 +178,7 @@ // CHECK-NEXT: Offset: 0x2038 // CHECK-NEXT: Size: 32 // CHECK-NEXT: Link: 9 -// CHECK-NEXT: Info: 1 +// CHECK-NEXT: Info: 2 // CHECK-NEXT: AddressAlignment: 4 // CHECK-NEXT: EntrySize: 16 // CHECK-NEXT: SectionData ( diff --git a/test/ELF/dtrace-r.test b/test/ELF/dtrace-r.test new file mode 100644 index 000000000000..2b6d885d4c89 --- /dev/null +++ b/test/ELF/dtrace-r.test @@ -0,0 +1,8 @@ +RUN: ld.lld -r -o %t.o %p/Inputs/dtrace-r.o +RUN: llvm-readobj -r %t.o | FileCheck %s + +CHECK: Relocations [ +CHECK-NEXT: Section ({{.*}}) .rela.text { +CHECK-NEXT: 0x0 R_X86_64_NONE - 0x0 +CHECK-NEXT: } +CHECK-NEXT: ] |