[lld] r287913 - [ELF] - Add support for access to most of synthetic sections from linkerscript.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 25 00:05:41 PST 2016
Author: grimar
Date: Fri Nov 25 02:05:41 2016
New Revision: 287913
URL: http://llvm.org/viewvc/llvm-project?rev=287913&view=rev
Log:
[ELF] - Add support for access to most of synthetic sections from linkerscript.
This is important for cases like:
.sdata : {
*(.got.plt .got)
...
}
That was not supported before as there was no way to get access to
synthetic sections from script.
More details on review page.
Differential revision: https://reviews.llvm.org/D27040
Added:
lld/trunk/test/ELF/synthetic-got.s
Modified:
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Writer.cpp
lld/trunk/test/ELF/eh-align-cie.s
lld/trunk/test/ELF/eh-frame-hdr-augmentation.s
lld/trunk/test/ELF/eh-frame-marker.s
lld/trunk/test/ELF/eh-frame-merge.s
lld/trunk/test/ELF/linkerscript/phdrs.s
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=287913&r1=287912&r2=287913&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Fri Nov 25 02:05:41 2016
@@ -426,6 +426,12 @@ template <class ELFT> void GotSection<EL
Size = Entries.size() * sizeof(uintX_t);
}
+template <class ELFT> bool GotSection<ELFT>::empty() const {
+ // If we have a relocation that is relative to GOT (such as GOTOFFREL),
+ // we need to emit a GOT even if it's empty.
+ return Entries.empty() && !HasGotOffRel;
+}
+
template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
for (const SymbolBody *B : Entries) {
uint8_t *Entry = Buf;
@@ -614,6 +620,12 @@ template <class ELFT> void MipsGotSectio
Size = EntriesNum * sizeof(uintX_t);
}
+template <class ELFT> bool MipsGotSection<ELFT>::empty() const {
+ // We add the .got section to the result for dynamic MIPS target because
+ // its address and properties are mentioned in the .dynamic section.
+ return Config->Relocatable;
+}
+
template <class ELFT> unsigned MipsGotSection<ELFT>::getGp() const {
return ElfSym<ELFT>::MipsGp->template getVA<ELFT>(0);
}
@@ -691,10 +703,6 @@ template <class ELFT> void GotPltSection
Entries.push_back(&Sym);
}
-template <class ELFT> bool GotPltSection<ELFT>::empty() const {
- return Entries.empty();
-}
-
template <class ELFT> size_t GotPltSection<ELFT>::getSize() const {
return (Target->GotPltHeaderEntriesNum + Entries.size()) *
Target->GotPltEntrySize;
@@ -808,7 +816,7 @@ template <class ELFT> void DynamicSectio
this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
- if (In<ELFT>::RelaDyn->hasRelocs()) {
+ if (!In<ELFT>::RelaDyn->empty()) {
bool IsRela = Config->Rela;
add({IsRela ? DT_RELA : DT_REL, In<ELFT>::RelaDyn});
add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->getSize()});
@@ -824,7 +832,7 @@ template <class ELFT> void DynamicSectio
add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels});
}
}
- if (In<ELFT>::RelaPlt->hasRelocs()) {
+ if (!In<ELFT>::RelaPlt->empty()) {
add({DT_JMPREL, In<ELFT>::RelaPlt});
add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getSize()});
add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
@@ -1490,6 +1498,10 @@ void EhFrameHeader<ELFT>::addFde(uint32_
Fdes.push_back({Pc, FdeVA});
}
+template <class ELFT> bool EhFrameHeader<ELFT>::empty() const {
+ return Out<ELFT>::EhFrame->empty();
+}
+
template <class ELFT>
VersionDefinitionSection<ELFT>::VersionDefinitionSection()
: SyntheticSection<ELFT>(SHF_ALLOC, SHT_GNU_verdef, sizeof(uint32_t),
@@ -1573,6 +1585,10 @@ template <class ELFT> void VersionTableS
}
}
+template <class ELFT> bool VersionTableSection<ELFT>::empty() const {
+ return !In<ELFT>::VerDef && In<ELFT>::VerNeed->empty();
+}
+
template <class ELFT>
VersionNeedSection<ELFT>::VersionNeedSection()
: SyntheticSection<ELFT>(SHF_ALLOC, SHT_GNU_verneed, sizeof(uint32_t),
@@ -1654,6 +1670,10 @@ template <class ELFT> size_t VersionNeed
return Size;
}
+template <class ELFT> bool VersionNeedSection<ELFT>::empty() const {
+ return getNeedNum() == 0;
+}
+
template <class ELFT>
MipsRldMapSection<ELFT>::MipsRldMapSection()
: SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=287913&r1=287912&r2=287913&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Fri Nov 25 02:05:41 2016
@@ -32,6 +32,7 @@ public:
virtual void writeTo(uint8_t *Buf) = 0;
virtual size_t getSize() const = 0;
virtual void finalize() {}
+ virtual bool empty() const { return false; }
uintX_t getVA() const {
return this->OutSec ? this->OutSec->Addr + this->OutSecOff : 0;
@@ -50,10 +51,11 @@ public:
void writeTo(uint8_t *Buf) override;
size_t getSize() const override { return Size; }
void finalize() override;
+ bool empty() const override;
+
void addEntry(SymbolBody &Sym);
bool addDynTlsEntry(SymbolBody &Sym);
bool addTlsIndex();
- bool empty() const { return Entries.empty(); }
uintX_t getGlobalDynAddr(const SymbolBody &B) const;
uintX_t getGlobalDynOffset(const SymbolBody &B) const;
@@ -98,6 +100,7 @@ public:
void writeTo(uint8_t *Buf) override;
size_t getSize() const override { return Size; }
void finalize() override;
+ bool empty() const override;
void addEntry(SymbolBody &Sym, uintX_t Addend, RelExpr Expr);
bool addDynTlsEntry(SymbolBody &Sym);
bool addTlsIndex();
@@ -194,9 +197,9 @@ class GotPltSection final : public Synth
public:
GotPltSection();
void addEntry(SymbolBody &Sym);
- bool empty() const;
size_t getSize() const override;
void writeTo(uint8_t *Buf) override;
+ bool empty() const override { return Entries.empty(); }
private:
std::vector<const SymbolBody *> Entries;
@@ -315,8 +318,8 @@ public:
unsigned getRelocOffset();
void finalize() override;
void writeTo(uint8_t *Buf) override;
+ bool empty() const override { return Relocs.empty(); }
size_t getSize() const override { return Relocs.size() * this->Entsize; }
- bool hasRelocs() const { return !Relocs.empty(); }
size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
private:
@@ -421,7 +424,7 @@ public:
void writeTo(uint8_t *Buf) override;
size_t getSize() const override;
void addEntry(SymbolBody &Sym);
- bool empty() const { return Entries.empty(); }
+ bool empty() const override { return Entries.empty(); }
private:
std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
@@ -471,6 +474,7 @@ public:
void writeTo(uint8_t *Buf) override;
size_t getSize() const override;
void addFde(uint32_t Pc, uint32_t FdeVA);
+ bool empty() const override;
private:
struct FdeData {
@@ -521,6 +525,7 @@ public:
void finalize() override;
size_t getSize() const override;
void writeTo(uint8_t *Buf) override;
+ bool empty() const override;
};
// The .gnu.version_r section defines the version identifiers used by
@@ -547,6 +552,7 @@ public:
void writeTo(uint8_t *Buf) override;
size_t getSize() const override;
size_t getNeedNum() const { return Needed.size(); }
+ bool empty() const override;
};
// .MIPS.abiflags section.
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=287913&r1=287912&r2=287913&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Nov 25 02:05:41 2016
@@ -58,7 +58,6 @@ private:
void sortSections();
void finalizeSections();
void addPredefinedSections();
- bool needsGot();
std::vector<Phdr> createPhdrs();
void assignAddresses();
@@ -242,8 +241,6 @@ template <class ELFT> void Writer<ELFT>:
In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
In<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false);
- In<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
- In<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
Out<ELFT>::ElfHeader = make<OutputSectionBase>("", 0, SHF_ALLOC);
Out<ELFT>::ElfHeader->Size = sizeof(Elf_Ehdr);
@@ -257,17 +254,9 @@ template <class ELFT> void Writer<ELFT>:
In<ELFT>::Interp = nullptr;
}
- if (!Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic) {
- In<ELFT>::DynSymTab = make<SymbolTableSection<ELFT>>(*In<ELFT>::DynStrTab);
- }
-
if (Config->EhFrameHdr)
In<ELFT>::EhFrameHdr = make<EhFrameHeader<ELFT>>();
- if (Config->GnuHash)
- In<ELFT>::GnuHashTab = make<GnuHashTableSection<ELFT>>();
- if (Config->SysvHash)
- In<ELFT>::HashTab = make<HashTableSection<ELFT>>();
if (Config->GdbIndex)
In<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>();
@@ -278,9 +267,6 @@ template <class ELFT> void Writer<ELFT>:
In<ELFT>::SymTab = make<SymbolTableSection<ELFT>>(*In<ELFT>::StrTab);
}
- if (!Config->VersionDefinitions.empty())
- In<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>();
-
// Initialize linker generated sections
if (!Config->Relocatable)
Symtab<ELFT>::X->Sections.push_back(createCommentSection<ELFT>());
@@ -297,8 +283,9 @@ template <class ELFT> void Writer<ELFT>:
}
// Add MIPS-specific sections.
+ bool HasDynSymTab = !Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic;
if (Config->EMachine == EM_MIPS) {
- if (!Config->Shared && In<ELFT>::DynSymTab) {
+ if (!Config->Shared && HasDynSymTab) {
In<ELFT>::MipsRldMap = make<MipsRldMapSection<ELFT>>();
Symtab<ELFT>::X->Sections.push_back(In<ELFT>::MipsRldMap);
}
@@ -310,14 +297,48 @@ template <class ELFT> void Writer<ELFT>:
Symtab<ELFT>::X->Sections.push_back(Sec);
}
+ if (HasDynSymTab) {
+ In<ELFT>::DynSymTab = make<SymbolTableSection<ELFT>>(*In<ELFT>::DynStrTab);
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::DynSymTab);
+
+ In<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::VerSym);
+
+ if (!Config->VersionDefinitions.empty()) {
+ In<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::VerDef);
+ }
+
+ In<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::VerNeed);
+
+ if (Config->GnuHash) {
+ In<ELFT>::GnuHashTab = make<GnuHashTableSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::GnuHashTab);
+ }
+
+ if (Config->SysvHash) {
+ In<ELFT>::HashTab = make<HashTableSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::HashTab);
+ }
+
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Dynamic);
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::DynStrTab);
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::RelaDyn);
+ }
+
// Add .got. MIPS' .got is so different from the other archs,
// it has its own class.
- if (Config->EMachine == EM_MIPS)
+ if (Config->EMachine == EM_MIPS) {
In<ELFT>::MipsGot = make<MipsGotSection<ELFT>>();
- else
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::MipsGot);
+ } else {
In<ELFT>::Got = make<GotSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Got);
+ }
In<ELFT>::GotPlt = make<GotPltSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::GotPlt);
}
template <class ELFT>
@@ -870,6 +891,30 @@ finalizeSynthetic(const std::vector<Synt
}
}
+// We need to add input synthetic sections early in createSyntheticSections()
+// to make them visible from linkescript side. But not all sections are always
+// required to be in output. For example we don't need dynamic section content
+// sometimes. This function filters out such unused sections from output.
+template <class ELFT>
+static void removeUnusedSyntheticSections(std::vector<OutputSectionBase *> &V) {
+ // Input synthetic sections are placed after all regular ones. We iterate over
+ // them all and exit at first non-synthetic.
+ for (InputSectionBase<ELFT> *S : llvm::reverse(Symtab<ELFT>::X->Sections)) {
+ SyntheticSection<ELFT> *SS = dyn_cast<SyntheticSection<ELFT>>(S);
+ if (!SS)
+ return;
+ if (!SS->empty() || !SS->OutSec)
+ continue;
+
+ OutputSection<ELFT> *OutSec = cast<OutputSection<ELFT>>(SS->OutSec);
+ OutSec->Sections.erase(
+ std::find(OutSec->Sections.begin(), OutSec->Sections.end(), SS));
+ // If there is no other sections in output section, remove it from output.
+ if (OutSec->Sections.empty())
+ V.erase(std::find(V.begin(), V.end(), OutSec));
+ }
+}
+
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::finalizeSections() {
Out<ELFT>::DebugInfo = findSection(".debug_info");
@@ -930,6 +975,7 @@ template <class ELFT> void Writer<ELFT>:
// So far we have added sections from input object files.
// This function adds linker-created Out<ELFT>::* sections.
addPredefinedSections();
+ removeUnusedSyntheticSections<ELFT>(OutputSections);
sortSections();
@@ -956,20 +1002,6 @@ template <class ELFT> void Writer<ELFT>:
In<ELFT>::VerNeed, In<ELFT>::Dynamic});
}
-template <class ELFT> bool Writer<ELFT>::needsGot() {
- // We add the .got section to the result for dynamic MIPS target because
- // its address and properties are mentioned in the .dynamic section.
- if (Config->EMachine == EM_MIPS)
- return !Config->Relocatable;
-
- if (!In<ELFT>::Got->empty())
- return true;
-
- // If we have a relocation that is relative to GOT (such as GOTOFFREL),
- // we need to emit a GOT even if it's empty.
- return In<ELFT>::Got->HasGotOffRel;
-}
-
// This function add Out<ELFT>::* sections to OutputSections.
template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
auto Add = [&](OutputSectionBase *OS) {
@@ -984,41 +1016,12 @@ template <class ELFT> void Writer<ELFT>:
addInputSec(In<ELFT>::SymTab);
addInputSec(In<ELFT>::ShStrTab);
addInputSec(In<ELFT>::StrTab);
- if (In<ELFT>::DynSymTab) {
- addInputSec(In<ELFT>::DynSymTab);
-
- bool HasVerNeed = In<ELFT>::VerNeed->getNeedNum() != 0;
- if (In<ELFT>::VerDef || HasVerNeed)
- addInputSec(In<ELFT>::VerSym);
- addInputSec(In<ELFT>::VerDef);
- if (HasVerNeed)
- addInputSec(In<ELFT>::VerNeed);
-
- addInputSec(In<ELFT>::GnuHashTab);
- addInputSec(In<ELFT>::HashTab);
- addInputSec(In<ELFT>::Dynamic);
- addInputSec(In<ELFT>::DynStrTab);
- if (In<ELFT>::RelaDyn->hasRelocs())
- addInputSec(In<ELFT>::RelaDyn);
- }
// We always need to add rel[a].plt to output if it has entries.
// Even during static linking it can contain R_[*]_IRELATIVE relocations.
- if (In<ELFT>::RelaPlt->hasRelocs())
+ if (!In<ELFT>::RelaPlt->empty())
addInputSec(In<ELFT>::RelaPlt);
- // We fill .got and .got.plt sections in scanRelocs(). This is the
- // reason we don't add it earlier in createSections().
- if (needsGot()) {
- if (Config->EMachine == EM_MIPS)
- addInputSec(In<ELFT>::MipsGot);
- else
- addInputSec(In<ELFT>::Got);
- }
-
- if (!In<ELFT>::GotPlt->empty())
- addInputSec(In<ELFT>::GotPlt);
-
if (!In<ELFT>::Plt->empty())
addInputSec(In<ELFT>::Plt);
if (!Out<ELFT>::EhFrame->empty())
Modified: lld/trunk/test/ELF/eh-align-cie.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/eh-align-cie.s?rev=287913&r1=287912&r2=287913&view=diff
==============================================================================
--- lld/trunk/test/ELF/eh-align-cie.s (original)
+++ lld/trunk/test/ELF/eh-align-cie.s Fri Nov 25 02:05:41 2016
@@ -51,7 +51,7 @@ bar:
// CHECK-NEXT: EntrySize:
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 1C000000 00000000 017A5052 00017810
-// CHECK-NEXT: 0010: 061B260E 00001B0C 07089001 00000000
-// CHECK-NEXT: 0020: 14000000 24000000 100E0000 00000000
+// CHECK-NEXT: 0010: 061BF60D 00001B0C 07089001 00000000
+// CHECK-NEXT: 0020: 14000000 24000000 E00D0000 00000000
// CHECK-NEXT: 0030: 00000000 00000000
// CHECK-NEXT: )
Modified: lld/trunk/test/ELF/eh-frame-hdr-augmentation.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/eh-frame-hdr-augmentation.s?rev=287913&r1=287912&r2=287913&view=diff
==============================================================================
--- lld/trunk/test/ELF/eh-frame-hdr-augmentation.s (original)
+++ lld/trunk/test/ELF/eh-frame-hdr-augmentation.s Fri Nov 25 02:05:41 2016
@@ -18,7 +18,7 @@
// CHECK-NEXT: DW_CFA_nop:
// CHECK-NEXT: DW_CFA_nop:
-// CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00000dd8...00000dd8
+// CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00000da8...00000da8
// CHECK-NEXT: DW_CFA_nop:
// CHECK-NEXT: DW_CFA_nop:
// CHECK-NEXT: DW_CFA_nop:
Modified: lld/trunk/test/ELF/eh-frame-marker.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/eh-frame-marker.s?rev=287913&r1=287912&r2=287913&view=diff
==============================================================================
--- lld/trunk/test/ELF/eh-frame-marker.s (original)
+++ lld/trunk/test/ELF/eh-frame-marker.s Fri Nov 25 02:05:41 2016
@@ -8,10 +8,10 @@
// CHECK-NEXT: Flags [
// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x200
+// CHECK-NEXT: Address: 0x229
// CHECK: Name: foo
-// CHECK-NEXT: Value: 0x200
+// CHECK-NEXT: Value: 0x229
.section .eh_frame
foo:
Modified: lld/trunk/test/ELF/eh-frame-merge.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/eh-frame-merge.s?rev=287913&r1=287912&r2=287913&view=diff
==============================================================================
--- lld/trunk/test/ELF/eh-frame-merge.s (original)
+++ lld/trunk/test/ELF/eh-frame-merge.s Fri Nov 25 02:05:41 2016
@@ -35,10 +35,10 @@
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 14000000 00000000 017A5200 01781001 |
// CHECK-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000 |
-// CHECK-NEXT: 0020: 180E0000 01000000 00000000 00000000 |
-// CHECK-NEXT: 0030: 14000000 34000000 020E0000 02000000 |
+// CHECK-NEXT: 0020: E80D0000 01000000 00000000 00000000 |
+// CHECK-NEXT: 0030: 14000000 34000000 D20D0000 02000000 |
// CHECK-NEXT: 0040: 00000000 00000000 14000000 4C000000 |
-// CHECK-NEXT: 0050: E90D0000 01000000 00000000 00000000 |
+// CHECK-NEXT: 0050: B90D0000 01000000 00000000 00000000 |
// CHECK-NEXT: )
// CHECK: Name: foo
Modified: lld/trunk/test/ELF/linkerscript/phdrs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/phdrs.s?rev=287913&r1=287912&r2=287913&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/phdrs.s (original)
+++ lld/trunk/test/ELF/linkerscript/phdrs.s Fri Nov 25 02:05:41 2016
@@ -102,7 +102,7 @@
# INT-PHDRS-NEXT: PF_W
# INT-PHDRS-NEXT: PF_X
# INT-PHDRS-NEXT: ]
-# INT-PHDRS-NEXT: Alignment: 4
+# INT-PHDRS-NEXT: Alignment:
# INT-PHDRS-NEXT: }
# INT-PHDRS-NEXT: ]
Added: lld/trunk/test/ELF/synthetic-got.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/synthetic-got.s?rev=287913&view=auto
==============================================================================
--- lld/trunk/test/ELF/synthetic-got.s (added)
+++ lld/trunk/test/ELF/synthetic-got.s Fri Nov 25 02:05:41 2016
@@ -0,0 +1,32 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "SECTIONS { }" > %t0.script
+# RUN: ld.lld -shared %t.o -o %t0.out --script %t0.script
+# RUN: llvm-objdump -section-headers %t0.out | FileCheck %s --check-prefix=GOT
+# RUN: llvm-objdump -s -section=.got -section=.got.plt %t0.out \
+# RUN: | FileCheck %s --check-prefix=GOTDATA
+
+# GOT: Sections:
+# GOT: 9 .got 00000008 00000000000001b0 DATA
+# GOT-NEXT: 10 .got.plt 00000020 00000000000001b8 DATA
+# GOTDATA: Contents of section .got:
+# GOTDATA-NEXT: 01b0 00000000 00000000
+# GOTDATA-NEXT: Contents of section .got.plt:
+# GOTDATA-NEXT: 01b8 e0000000 00000000 00000000 00000000
+# GOTDATA-NEXT: 01c8 00000000 00000000 d6000000 00000000
+
+# RUN: echo "SECTIONS { .mygot : { *(.got) *(.got.plt) } }" > %t1.script
+# RUN: ld.lld -shared %t.o -o %t1.out --script %t1.script
+# RUN: llvm-objdump -section-headers %t1.out | FileCheck %s --check-prefix=MYGOT
+# RUN: llvm-objdump -s -section=.mygot %t1.out | FileCheck %s --check-prefix=MYGOTDATA
+
+# MYGOT: Sections:
+# MYGOT: 9 .mygot 00000028 00000000000001b0 DATA
+# MYGOT-NOT: .got
+# MYGOT-NOT: .got.plt
+# MYGOTDATA: 01b0 00000000 00000000 e0000000 00000000
+# MYGOTDATA-NEXT: 01c0 00000000 00000000 00000000 00000000
+# MYGOTDATA-NEXT: 01d0 d6000000 00000000
+
+mov bar at gotpcrel(%rip), %rax
+call foo at plt
More information about the llvm-commits
mailing list