diff options
| author | Michael J. Spencer <bigcheesegs@gmail.com> | 2013-03-01 01:09:46 +0000 |
|---|---|---|
| committer | Michael J. Spencer <bigcheesegs@gmail.com> | 2013-03-01 01:09:46 +0000 |
| commit | 8c0526593aa5564bef99c182f8e93efbef8081d1 (patch) | |
| tree | f1ada4a029f1744e97624efa64d2c901841199c8 | |
| parent | e44e30ca5a0763d8eb86f552514884ac4c97f8cb (diff) | |
| download | bcm5719-llvm-8c0526593aa5564bef99c182f8e93efbef8081d1.tar.gz bcm5719-llvm-8c0526593aa5564bef99c182f8e93efbef8081d1.zip | |
[Writer][ELF][x86-64] Handle GOTPCREL relocations to SharedLibraryAtoms.
llvm-svn: 176324
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp | 25 | ||||
| -rw-r--r-- | lld/test/elf/Inputs/shared.c | 3 | ||||
| -rw-r--r-- | lld/test/elf/Inputs/shared.so-x86-64 | bin | 8125 -> 8195 bytes | |||
| -rw-r--r-- | lld/test/elf/Inputs/use-shared.c | 2 | ||||
| -rw-r--r-- | lld/test/elf/Inputs/use-shared.x86-64 | bin | 1264 -> 1376 bytes | |||
| -rw-r--r-- | lld/test/elf/dynamic.test | 10 | ||||
| -rw-r--r-- | lld/test/elf/x86-64-dynamic.test | 16 |
7 files changed, 52 insertions, 4 deletions
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp index 7e6f0be6e73..f3c2f4703da 100644 --- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp +++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp @@ -409,6 +409,31 @@ public: return handlePLT32(ref); return handleIFUNC(ref); } + + const GOTAtom *getSharedGOT(const SharedLibraryAtom *sla) { + auto got = _gotMap.find(sla); + if (got == _gotMap.end()) { + auto g = new (_file._alloc) GOTAtom(_file, ".got.dyn"); + g->addReference(R_X86_64_GLOB_DAT, 0, sla, 0); +#ifndef NDEBUG + g->_name = "__got_"; + g->_name += sla->name(); +#endif + _gotMap[sla] = g; + return g; + } + return got->second; + } + + void handleGOTPCREL(const Reference &ref) { + const_cast<Reference &>(ref).setKind(R_X86_64_PC32); + if (isa<UndefinedAtom>(ref.target())) + const_cast<Reference &>(ref).setTarget(getNullGOT()); + else if (const DefinedAtom *da = dyn_cast<const DefinedAtom>(ref.target())) + const_cast<Reference &>(ref).setTarget(getGOT(da)); + else if (const auto sla = dyn_cast<const SharedLibraryAtom>(ref.target())) + const_cast<Reference &>(ref).setTarget(getSharedGOT(sla)); + } }; } // end anon namespace diff --git a/lld/test/elf/Inputs/shared.c b/lld/test/elf/Inputs/shared.c index 9bf69f83f6e..a10944fd8d6 100644 --- a/lld/test/elf/Inputs/shared.c +++ b/lld/test/elf/Inputs/shared.c @@ -1,5 +1,8 @@ #include <stdio.h> +extern int i; +int i = 42; + void foo() { puts("Fooo!!"); } diff --git a/lld/test/elf/Inputs/shared.so-x86-64 b/lld/test/elf/Inputs/shared.so-x86-64 Binary files differindex cc2fe5610ba..77625700fc6 100644 --- a/lld/test/elf/Inputs/shared.so-x86-64 +++ b/lld/test/elf/Inputs/shared.so-x86-64 diff --git a/lld/test/elf/Inputs/use-shared.c b/lld/test/elf/Inputs/use-shared.c index 54332356b0b..b370eaa4fac 100644 --- a/lld/test/elf/Inputs/use-shared.c +++ b/lld/test/elf/Inputs/use-shared.c @@ -1,5 +1,7 @@ +extern int i; void foo(); int main() { foo(); + return i; } diff --git a/lld/test/elf/Inputs/use-shared.x86-64 b/lld/test/elf/Inputs/use-shared.x86-64 Binary files differindex f7236ff6973..25e1eb87a2b 100644 --- a/lld/test/elf/Inputs/use-shared.x86-64 +++ b/lld/test/elf/Inputs/use-shared.x86-64 diff --git a/lld/test/elf/dynamic.test b/lld/test/elf/dynamic.test index 548613c1113..df9d10e5d9e 100644 --- a/lld/test/elf/dynamic.test +++ b/lld/test/elf/dynamic.test @@ -28,22 +28,26 @@ CHECK: flags r-- CHECK: Dynamic Symbols: CHECK: foo FUNC {{[0-9a-f]+}} 0 {{[0-9a-f]+}} undef,global -CHECK: Total: 1 +CHECK: i FUNC {{[0-9a-f]+}} 0 {{[0-9a-f]+}} undef,global +CHECK: Total: 2 CHECK: Sections: CHECK: .hash {{[0-9a-f]+}} 8 4 required,rodata -CHECK: Dynamic section contains 11 entries +CHECK: Dynamic section contains 14 entries CHECK: Tag Type Name/Value CHECK: 0x0000000000000004 (HASH) CHECK: 0x0000000000000005 (STRTAB) CHECK: 0x0000000000000006 (SYMTAB) CHECK: 0x000000000000000a (STRSZ) CHECK: 0x000000000000000b (SYMENT) 24 +CHECK: 0x0000000000000007 (RELA) +CHECK: 0x0000000000000008 (RELASZ) 24 +CHECK: 0x0000000000000009 (RELAENT) 24 CHECK: 0x0000000000000002 (PLTRELSZ) 24 CHECK: 0x0000000000000003 (PLTGOT) CHECK: 0x0000000000000014 (PLTREL) RELA CHECK: 0x0000000000000017 (JMPREL) CHECK: 0x0000000000000001 (NEEDED) Shared library: [shared.so-x86-64] CHECK: 0x0000000000000000 (NULL) 0x0 -CHECK: Total: 11 +CHECK: Total: 14 diff --git a/lld/test/elf/x86-64-dynamic.test b/lld/test/elf/x86-64-dynamic.test index 591d69e7b16..dce439631ee 100644 --- a/lld/test/elf/x86-64-dynamic.test +++ b/lld/test/elf/x86-64-dynamic.test @@ -25,6 +25,16 @@ CHECK: alignment: 2^3 CHECK: section-choice: custom-required CHECK: section-name: .got.plt CHECK: permissions: rw- + - name: __got_i +CHECK: type: got +CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ] +CHECK: section-choice: custom-required +CHECK: section-name: .got.dyn +CHECK: permissions: rw- +CHECK: references: +CHECK: - kind: R_X86_64_GLOB_DAT +CHECK: offset: 0 +CHECK: target: i - name: __got_foo CHECK: type: got CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ] @@ -45,9 +55,13 @@ CHECK: - name: main CHECK: scope: global CHECK: references: CHECK: - kind: R_X86_64_PC32 -CHECK: offset: 7 +CHECK: offset: 18 target: __plt_foo CHECK: addend: -4 +CHECK: - kind: R_X86_64_PC32 +CHECK: offset: 25 + target: __got_i +CHECK: addend: -4 - name: .PLT0 CHECK: type: stub |

