[llvm-dev] Compatibility issue with go
Rafael EspĂndola via llvm-dev
llvm-dev at lists.llvm.org
Fri Feb 10 14:44:01 PST 2017
The attached patch fixes the issue with Elf_Rela. I checked that the
go binary now works.
Unfortunately it completely breaks -r with Elf_Rel. I am investigating
what is the best way to fix it.
Cheers,
Rafael
On 9 February 2017 at 19:47, Rafael Avila de Espindola
<rafael.espindola at gmail.com> wrote:
> Rui Ueyama <ruiu at google.com> writes:
>
>> Does Go use the system linker? Go is written in Go, and I was thinking that
>> the Go toolchain includes everything from a compiler to a standard library
>> to a linker, and depends on very little on the host system.
>
> Looks like all that they are missing is "ld -r" :-(
>
> Cheers,
> Rafael
-------------- next part --------------
diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp
index 235d500..dddb932 100644
--- a/ELF/InputSection.cpp
+++ b/ELF/InputSection.cpp
@@ -228,20 +228,24 @@ void InputSection<ELFT>::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
// simple linear search.
for (const RelTy &Rel : Rels) {
uint32_t Type = Rel.getType(Config->Mips64EL);
- SymbolBody &Body = this->File->getRelocTargetSym(Rel);
+ SymbolBody *Body = &this->File->getRelocTargetSym(Rel);
Elf_Rela *P = reinterpret_cast<Elf_Rela *>(Buf);
Buf += sizeof(RelTy);
+ size_t Index = In<ELFT>::SymTab->getSymbolIndex(Body);
- if (Config->Rela)
+ if (Config->Rela) {
P->r_addend = getAddend<ELFT>(Rel);
+ if (Body->Type == STT_SECTION)
+ P->r_addend += Body->getVA<ELFT>() -
+ cast<DefinedRegular<ELFT>>(Body)->Section->OutSec->Addr;
+ }
// Output section VA is zero for -r, so r_offset is an offset within the
// section, but for --emit-relocs it is an virtual address.
P->r_offset = RelocatedSection->OutSec->Addr +
RelocatedSection->getOffset(Rel.r_offset);
- P->setSymbolAndType(In<ELFT>::SymTab->getSymbolIndex(&Body), Type,
- Config->Mips64EL);
+ P->setSymbolAndType(Index, Type, Config->Mips64EL);
}
}
diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp
index 70a338b..26b9072 100644
--- a/ELF/SyntheticSections.cpp
+++ b/ELF/SyntheticSections.cpp
@@ -1127,8 +1127,14 @@ template <class ELFT> void SymbolTableSection<ELFT>::addLocal(SymbolBody *B) {
template <class ELFT>
size_t SymbolTableSection<ELFT>::getSymbolIndex(SymbolBody *Body) {
- auto I = llvm::find_if(
- Symbols, [&](const SymbolTableEntry &E) { return E.Symbol == Body; });
+ auto I = llvm::find_if(Symbols, [&](const SymbolTableEntry &E) {
+ if (E.Symbol == Body)
+ return true;
+ if (Body->Type == STT_SECTION && E.Symbol->Type == STT_SECTION)
+ return cast<DefinedRegular<ELFT>>(Body)->Section->OutSec ==
+ cast<DefinedRegular<ELFT>>(E.Symbol)->Section->OutSec;
+ return false;
+ });
if (I == Symbols.end())
return 0;
return I - Symbols.begin() + 1;
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index e158b7e..f8ce82e 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -51,6 +51,7 @@ public:
private:
void createSyntheticSections();
void copyLocalSymbols();
+ void addSectionSymbols();
void addReservedSymbols();
void addInputSec(InputSectionBase<ELFT> *S);
void createSections();
@@ -228,6 +229,9 @@ template <class ELFT> void Writer<ELFT>::run() {
if (Config->Discard != DiscardPolicy::All)
copyLocalSymbols();
+ if (Config->copyRelocs())
+ addSectionSymbols();
+
// Now that we have a complete set of output sections. This function
// completes section contents. For example, we need to add strings
// to the string table, and add entries to .got and .plt.
@@ -446,13 +450,9 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
template <class ELFT>
static bool shouldKeepInSymtab(InputSectionBase<ELFT> *Sec, StringRef SymName,
const SymbolBody &B) {
- if (B.isFile())
+ if (B.isFile() || B.isSection())
return false;
- // We keep sections in symtab for relocatable output and --emit-reloc.
- if (B.isSection())
- return Config->copyRelocs();
-
// If sym references a section in a discarded group, don't keep it.
if (Sec == &InputSection<ELFT>::Discarded)
return false;
@@ -518,6 +518,25 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
}
}
+template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
+ for (OutputSectionBase *Sec : OutputSections) {
+ InputSectionData *First = nullptr;
+ Sec->forEachInputSection([&](InputSectionData *D) {
+ if (!First)
+ First = D;
+ });
+ auto *IS = dyn_cast_or_null<InputSection<ELFT>>(First);
+ if (!IS || isa<SyntheticSection<ELFT>>(IS) || IS->Type == SHT_REL ||
+ IS->Type == SHT_RELA)
+ continue;
+ auto *B = new (BAlloc)
+ DefinedRegular<ELFT>("", /*IsLocal=*/true, /*StOther*/ 0, STT_SECTION,
+ /*Value*/ 0, /*Size*/ 0, IS, nullptr);
+
+ In<ELFT>::SymTab->addLocal(B);
+ }
+}
+
// PPC64 has a number of special SHT_PROGBITS+SHF_ALLOC+SHF_WRITE sections that
// we would like to make sure appear is a specific order to maximize their
// coverage by a single signed 16-bit offset from the TOC base pointer.
diff --git a/test/ELF/emit-relocs.s b/test/ELF/emit-relocs.s
index 10808fd..dfe2058 100644
--- a/test/ELF/emit-relocs.s
+++ b/test/ELF/emit-relocs.s
@@ -15,7 +15,7 @@
# CHECK-NEXT: Section ({{.*}}) .rela.text {
# CHECK-NEXT: 0x201002 R_X86_64_32 .text 0x1
# CHECK-NEXT: 0x201007 R_X86_64_PLT32 fn 0xFFFFFFFFFFFFFFFC
-# CHECK-NEXT: 0x20100E R_X86_64_32 .text 0x1
+# CHECK-NEXT: 0x20100E R_X86_64_32 .text 0xD
# CHECK-NEXT: 0x201013 R_X86_64_PLT32 fn2 0xFFFFFFFFFFFFFFFC
# CHECK-NEXT: }
# CHECK-NEXT: ]
@@ -57,15 +57,6 @@
# CHECK-NEXT: Section: .text
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name:
-# CHECK-NEXT: Value: 0x20100C
-# CHECK-NEXT: Size: 0
-# CHECK-NEXT: Binding: Local
-# CHECK-NEXT: Type: Section
-# CHECK-NEXT: Other: 0
-# CHECK-NEXT: Section: .text
-# CHECK-NEXT: }
-# CHECK-NEXT: Symbol {
# CHECK-NEXT: Name: fn
# CHECK-NEXT: Value: 0x201000
# CHECK-NEXT: Size: 0
diff --git a/test/ELF/mips-sto-pic-flag.s b/test/ELF/mips-sto-pic-flag.s
index 4d79233..3960ba3 100644
--- a/test/ELF/mips-sto-pic-flag.s
+++ b/test/ELF/mips-sto-pic-flag.s
@@ -19,8 +19,8 @@
# CHECK-NEXT: Other: 0
# CHECK-NEXT: Section: .text
# CHECK-NEXT: }
-# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: foo1a
+# CHECK: Symbol {
+# CHECK: Name: foo1a
# CHECK-NEXT: Value:
# CHECK-NEXT: Size:
# CHECK-NEXT: Binding: Global
diff --git a/test/ELF/relocatable-bss.s b/test/ELF/relocatable-bss.s
index 0411bf3..becfbae 100644
--- a/test/ELF/relocatable-bss.s
+++ b/test/ELF/relocatable-bss.s
@@ -20,7 +20,7 @@
# CHECK-NEXT: Version:
# CHECK-NEXT: Entry:
# CHECK-NEXT: ProgramHeaderOffset:
-# CHECK-NEXT: SectionHeaderOffset: 0xA8
+# CHECK-NEXT: SectionHeaderOffset: 0xD8
# CHECK-NEXT: Flags [
# CHECK-NEXT: ]
# CHECK-NEXT: HeaderSize:
diff --git a/test/ELF/relocatable-section-symbol.s b/test/ELF/relocatable-section-symbol.s
new file mode 100644
index 0000000..ac18cf6
--- /dev/null
+++ b/test/ELF/relocatable-section-symbol.s
@@ -0,0 +1,49 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld -r -o %t %t.o %t.o
+# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELA %s
+
+# RELA: Relocations [
+# RELA-NEXT: Section ({{.*}}) .rela.data {
+# RELA-NEXT: 0x0 R_X86_64_32 .text 0x0
+# RELA-NEXT: 0x4 R_X86_64_32 .text 0x4
+# RELA-NEXT: }
+# RELA-NEXT: ]
+
+
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
+# RUN: ld.lld -r -o %t %t.o %t.o
+# RUN: llvm-readobj -r -s -section-data %t | FileCheck --check-prefix=REL %s
+
+
+# REL: Section {
+# REL: Index:
+# REL: Name: .data
+# REL-NEXT: Type: SHT_PROGBITS
+# REL-NEXT: Flags [
+# REL-NEXT: SHF_ALLOC
+# REL-NEXT: SHF_WRITE
+# REL-NEXT: ]
+# REL-NEXT: Address:
+# REL-NEXT: Offset:
+# REL-NEXT: Size:
+# REL-NEXT: Link:
+# REL-NEXT: Info:
+# REL-NEXT: AddressAlignment:
+# REL-NEXT: EntrySize:
+# REL-NEXT: SectionData (
+# REL-NEXT: 0000: 00000000 00000000 |
+# REL-NEXT: )
+# REL-NEXT: }
+
+
+# REL: Relocations [
+# REL-NEXT: Section ({{.*}}) .rel.data {
+# REL-NEXT: 0x0 R_386_32 .text 0x0
+# REL-NEXT: 0x4 R_386_32 .text 0x0
+# REL-NEXT: }
+# REL-NEXT: ]
+
+
+.long 42
+.data
+.long .text
More information about the llvm-dev
mailing list