[lld] r204247 - [Mips] Fix handling of R_MIPS_GOT16 relocation and building local part
Simon Atanasyan
simon at atanasyan.com
Wed Mar 19 08:46:25 PDT 2014
Author: atanasyan
Date: Wed Mar 19 10:46:25 2014
New Revision: 204247
URL: http://llvm.org/viewvc/llvm-project?rev=204247&view=rev
Log:
[Mips] Fix handling of R_MIPS_GOT16 relocation and building local part
of GOT.
* Read addend for R_MIPS_GOT16 relocation.
* Put only high 16 bits of symbol + addend into GOT entries for
locally visible symbols.
Modified:
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
lld/trunk/test/elf/Mips/dynlib-dynsym.test
lld/trunk/test/elf/Mips/got16.test
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h?rev=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h Wed Mar 19 10:46:25 2014
@@ -78,6 +78,7 @@ private:
break;
case R_MIPS_HI16:
case R_MIPS_LO16:
+ case R_MIPS_GOT16:
ref->setAddend(*(int16_t *)ap);
break;
}
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h?rev=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h Wed Mar 19 10:46:25 2014
@@ -18,6 +18,8 @@ namespace elf {
enum {
/// \brief Do nothing but mark GOT entry as a global one.
LLD_R_MIPS_GLOBAL_GOT = 1024,
+ /// \brief Apply high 16 bits of symbol + addend.
+ LLD_R_MIPS_32_HI16 = 1025,
/// \brief The same as R_MIPS_26 but for global symbols.
LLD_R_MIPS_GLOBAL_26 = 1026,
/// \brief Setup hi 16 bits using the symbol this reference refers to.
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp?rev=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Wed Mar 19 10:46:25 2014
@@ -105,6 +105,11 @@ void relocCall16(uint8_t *location, uint
applyReloc(location, G, 0xffff);
}
+/// \brief LLD_R_MIPS_32_HI16
+void reloc32hi16(uint8_t *location, uint64_t S, int64_t A) {
+ applyReloc(location, (S + A) & 0xffff0000, 0xffffffff);
+}
+
/// \brief LLD_R_MIPS_HI16
void relocLldHi16(uint8_t *location, uint64_t S) {
applyReloc(location, (S + 0x8000) >> 16, 0xffff);
@@ -164,6 +169,9 @@ error_code MipsTargetRelocationHandler::
case LLD_R_MIPS_GLOBAL_GOT:
// Do nothing.
break;
+ case LLD_R_MIPS_32_HI16:
+ reloc32hi16(location, targetVAddress, ref.addend());
+ break;
case LLD_R_MIPS_GLOBAL_26:
reloc26ext(location, targetVAddress, ref.addend());
break;
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp?rev=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp Wed Mar 19 10:46:25 2014
@@ -125,8 +125,11 @@ private:
/// \brief Owner of all the Atoms created by this pass.
RelocationPassFile _file;
- /// \brief Map Atoms to their GOT entries.
- llvm::DenseMap<const Atom *, GOTAtom *> _gotLocalMap;
+ /// \brief Map Atoms and addend to local GOT entries.
+ typedef std::pair<const Atom *, int64_t> LocalGotMapKeyT;
+ llvm::DenseMap<LocalGotMapKeyT, GOTAtom *> _gotLocalMap;
+
+ /// \brief Map Atoms to global GOT entries.
llvm::DenseMap<const Atom *, GOTAtom *> _gotGlobalMap;
/// \brief the list of local GOT atoms.
@@ -160,7 +163,7 @@ private:
void handlePLT(const Reference &ref);
void handleGOT(const Reference &ref);
- const GOTAtom *getLocalGOTEntry(const Atom *a);
+ const GOTAtom *getLocalGOTEntry(const Reference &ref);
const GOTAtom *getGlobalGOTEntry(const Atom *a);
const PLTAtom *getPLTEntry(const Atom *a);
const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a);
@@ -302,7 +305,7 @@ void RelocationPass::handlePLT(const Ref
void RelocationPass::handleGOT(const Reference &ref) {
if (requireLocalGOT(ref.target()))
- const_cast<Reference &>(ref).setTarget(getLocalGOTEntry(ref.target()));
+ const_cast<Reference &>(ref).setTarget(getLocalGOTEntry(ref));
else
const_cast<Reference &>(ref).setTarget(getGlobalGOTEntry(ref.target()));
}
@@ -327,18 +330,23 @@ bool RelocationPass::requireLocalGOT(con
return false;
}
-const GOTAtom *RelocationPass::getLocalGOTEntry(const Atom *a) {
- auto got = _gotLocalMap.find(a);
+const GOTAtom *RelocationPass::getLocalGOTEntry(const Reference &ref) {
+ const Atom *a = ref.target();
+ LocalGotMapKeyT key(a, ref.addend());
+
+ auto got = _gotLocalMap.find(key);
if (got != _gotLocalMap.end())
return got->second;
auto ga = new (_file._alloc) GOT0Atom(_file);
- _gotLocalMap[a] = ga;
+ _gotLocalMap[key] = ga;
_localGotVector.push_back(ga);
- if (const DefinedAtom *da = dyn_cast<DefinedAtom>(a))
- ga->addReferenceELF_Mips(R_MIPS_32, 0, da, 0);
+ if (isLocal(a))
+ ga->addReferenceELF_Mips(LLD_R_MIPS_32_HI16, 0, a, ref.addend());
+ else
+ ga->addReferenceELF_Mips(R_MIPS_32, 0, a, 0);
DEBUG_WITH_TYPE("MipsGOT", {
ga->_name = "__got_";
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp?rev=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Wed Mar 19 10:46:25 2014
@@ -58,6 +58,7 @@ const Registry::KindStrings MipsTargetHa
LLD_KIND_STRING_ENTRY(R_MIPS_COPY),
LLD_KIND_STRING_ENTRY(R_MIPS_JUMP_SLOT),
LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_GOT),
+ LLD_KIND_STRING_ENTRY(LLD_R_MIPS_32_HI16),
LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_26),
LLD_KIND_STRING_ENTRY(LLD_R_MIPS_HI16),
LLD_KIND_STRING_ENTRY(LLD_R_MIPS_LO16),
Modified: lld/trunk/test/elf/Mips/dynlib-dynsym.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/dynlib-dynsym.test?rev=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/test/elf/Mips/dynlib-dynsym.test (original)
+++ lld/trunk/test/elf/Mips/dynlib-dynsym.test Wed Mar 19 10:46:25 2014
@@ -83,7 +83,7 @@
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: references:
-# CHECK-GOT: - kind: R_MIPS_32
+# CHECK-GOT: - kind: LLD_R_MIPS_32_HI16
# CHECK-GOT: offset: 0
# CHECK-GOT: target: L003
# CHECK-GOT: - ref-name: L004
@@ -94,7 +94,7 @@
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: references:
-# CHECK-GOT: - kind: R_MIPS_32
+# CHECK-GOT: - kind: LLD_R_MIPS_32_HI16
# CHECK-GOT: offset: 0
# CHECK-GOT: target: L005
# CHECK-GOT: - ref-name: L006
Modified: lld/trunk/test/elf/Mips/got16.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/got16.test?rev=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/test/elf/Mips/got16.test (original)
+++ lld/trunk/test/elf/Mips/got16.test Wed Mar 19 10:46:25 2014
@@ -6,105 +6,141 @@
# RUN: lld -flavor gnu -target mipsel -shared --noinhibit-exec -o %t2 %t1
# RUN: llvm-objdump -t -disassemble %t2 | FileCheck -check-prefix RAW %s
-
-# YAML: - ref-name: [[L002:[-a-zA-Z0-9_]+]]
-# YAML: type: got
-# YAML: content: [ 00, 00, 00, 00 ]
-# YAML: alignment: 2^2
-# YAML: section-choice: custom-required
-# YAML: section-name: .got
-# YAML: permissions: rw-
-# YAML: references:
-# YAML: - kind: R_MIPS_32
-# YAML: offset: 0
-# YAML: target: [[L003:[-a-zA-Z0-9_]+]]
-# YAML: - ref-name: [[L004:[-a-zA-Z0-9_]+]]
-# YAML: type: got
-# YAML: content: [ 00, 00, 00, 00 ]
-# YAML: alignment: 2^2
-# YAML: section-choice: custom-required
-# YAML: section-name: .got
-# YAML: permissions: rw-
-# YAML: references:
-# YAML: - kind: R_MIPS_32
-# YAML: offset: 0
-# YAML: target: hidden
-# YAML: - ref-name: [[L005:[-a-zA-Z0-9_]+]]
-# YAML: type: got
-# YAML: content: [ 00, 00, 00, 00 ]
-# YAML: alignment: 2^2
-# YAML: section-choice: custom-required
-# YAML: section-name: .got
-# YAML: permissions: rw-
-# YAML: references:
-# YAML: - kind: LLD_R_MIPS_GLOBAL_GOT
-# YAML: offset: 0
-# YAML: target: glob
-# YAML: - kind: R_MIPS_32
-# YAML: offset: 0
-# YAML: target: glob
-# YAML: - ref-name: [[L006:[-a-zA-Z0-9_]+]]
-# YAML: type: got
-# YAML: content: [ 00, 00, 00, 00 ]
-# YAML: alignment: 2^2
-# YAML: section-choice: custom-required
-# YAML: section-name: .got
-# YAML: permissions: rw-
-# YAML: references:
-# YAML: - kind: LLD_R_MIPS_GLOBAL_GOT
-# YAML: offset: 0
-# YAML: target: extern
-# YAML: - ref-name: [[L007:[-a-zA-Z0-9_]+]]
-# YAML: alignment: 2^2
-# YAML: references:
-# YAML: - kind: layout-after
-# YAML: offset: 0
-# YAML: target: glob
-# YAML: - name: glob
-# YAML: scope: global
-# YAML: content: [ 00, 00, 84, 8F, 00, 00, 84, 24, 00, 00, 84, 8F,
-# YAML: 00, 00, 84, 8F, 00, 00, 84, 8F ]
-# YAML: alignment: 2^2
-# YAML: references:
-# YAML: - kind: R_MIPS_LO16
-# YAML: offset: 4
-# YAML: target: [[L003]]
-# YAML: - kind: R_MIPS_GOT16
-# YAML: offset: 8
-# YAML: target: [[L004]]
-# YAML: - kind: R_MIPS_CALL16
-# YAML: offset: 12
-# YAML: target: [[L005]]
-# YAML: - kind: R_MIPS_CALL16
-# YAML: offset: 16
-# YAML: target: [[L006]]
+# Local GOT entries:
+# YAML: - ref-name: L003
+# YAML-NEXT: type: got
+# YAML-NEXT: content: [ 00, 00, 00, 00 ]
+# YAML-NEXT: alignment: 2^2
+# YAML-NEXT: section-choice: custom-required
+# YAML-NEXT: section-name: .got
+# YAML-NEXT: permissions: rw-
+# YAML-NEXT: references:
+# YAML-NEXT: - kind: LLD_R_MIPS_32_HI16
+# YAML-NEXT: offset: 0
+# YAML-NEXT: target: L006
+# YAML-NEXT: - ref-name: L005
+# YAML-NEXT: type: got
+# YAML-NEXT: content: [ 00, 00, 00, 00 ]
+# YAML-NEXT: alignment: 2^2
+# YAML-NEXT: section-choice: custom-required
+# YAML-NEXT: section-name: .got
+# YAML-NEXT: permissions: rw-
+# YAML-NEXT: references:
+# YAML-NEXT: - kind: LLD_R_MIPS_32_HI16
+# YAML-NEXT: offset: 0
+# YAML-NEXT: target: L006
+# YAML-NEXT: addend: 66048
+# YAML-NEXT: - ref-name: L007
+# YAML-NEXT: type: got
+# YAML-NEXT: content: [ 00, 00, 00, 00 ]
+# YAML-NEXT: alignment: 2^2
+# YAML-NEXT: section-choice: custom-required
+# YAML-NEXT: section-name: .got
+# YAML-NEXT: permissions: rw-
+# YAML-NEXT: references:
+# YAML-NEXT: - kind: R_MIPS_32
+# YAML-NEXT: offset: 0
+# YAML-NEXT: target: hidden
+
+# Global GOT entries:
+# YAML-NEXT: - ref-name: L008
+# YAML-NEXT: type: got
+# YAML-NEXT: content: [ 00, 00, 00, 00 ]
+# YAML-NEXT: alignment: 2^2
+# YAML-NEXT: section-choice: custom-required
+# YAML-NEXT: section-name: .got
+# YAML-NEXT: permissions: rw-
+# YAML-NEXT: references:
+# YAML-NEXT: - kind: LLD_R_MIPS_GLOBAL_GOT
+# YAML-NEXT: offset: 0
+# YAML-NEXT: target: glob
+# YAML-NEXT: - kind: R_MIPS_32
+# YAML-NEXT: offset: 0
+# YAML-NEXT: target: glob
+# YAML-NEXT: - ref-name: L009
+# YAML-NEXT: type: got
+# YAML-NEXT: content: [ 00, 00, 00, 00 ]
+# YAML-NEXT: alignment: 2^2
+# YAML-NEXT: section-choice: custom-required
+# YAML-NEXT: section-name: .got
+# YAML-NEXT: permissions: rw-
+# YAML-NEXT: references:
+# YAML-NEXT: - kind: LLD_R_MIPS_GLOBAL_GOT
+# YAML-NEXT: offset: 0
+# YAML-NEXT: target: extern
+
+# Function glob
+# YAML: - name: glob
+# YAML-NEXT: scope: global
+# YAML-NEXT: content: [ 00, 00, 84, 8F, 00, 00, 84, 24, 01, 00, 84, 8F,
+# YAML-NEXT: 00, 02, 84, 24, 00, 00, 84, 8F, 00, 00, 84, 8F,
+# YAML-NEXT: 00, 00, 84, 8F ]
+# YAML-NEXT: alignment: 2^2
+# YAML-NEXT: references:
+# YAML-NEXT: - kind: R_MIPS_GOT16
+# YAML-NEXT: offset: 0
+# YAML-NEXT: target: L003
+# YAML-NEXT: - kind: R_MIPS_LO16
+# YAML-NEXT: offset: 4
+# YAML-NEXT: target: L006
+# YAML-NEXT: - kind: R_MIPS_GOT16
+# YAML-NEXT: offset: 8
+# YAML-NEXT: target: L005
+# YAML-NEXT: addend: 66048
+# YAML-NEXT: - kind: R_MIPS_LO16
+# YAML-NEXT: offset: 12
+# YAML-NEXT: target: L006
+# YAML-NEXT: addend: 512
+# YAML-NEXT: - kind: R_MIPS_GOT16
+# YAML-NEXT: offset: 16
+# YAML-NEXT: target: L007
+# YAML-NEXT: - kind: R_MIPS_CALL16
+# YAML-NEXT: offset: 20
+# YAML-NEXT: target: L008
+# YAML-NEXT: - kind: R_MIPS_CALL16
+# YAML-NEXT: offset: 24
+# YAML-NEXT: target: L009
# RAW: Disassembly of section .text:
# RAW: glob:
-# RAW-NEXT: 148: 18 80 84 8f lw $4, -32744($gp)
-# RAW-NEXT: 14c: 00 20 84 24 addiu $4, $4, 8192
-# RAW-NEXT: 150: 1c 80 84 8f lw $4, -32740($gp)
-# RAW-NEXT: 154: 20 80 84 8f lw $4, -32736($gp)
-# RAW-NEXT: 158: 24 80 84 8f lw $4, -32732($gp)
+# RAW-NEXT: 12c: 18 80 84 8f lw $4, -32744($gp)
+# RAW-NEXT: 130: 00 20 84 24 addiu $4, $4, 8192
+# RAW-NEXT: 134: 1c 80 84 8f lw $4, -32740($gp)
+# RAW-NEXT: 138: 00 22 84 24 addiu $4, $4, 8704
+# RAW-NEXT: 13c: 20 80 84 8f lw $4, -32736($gp)
+# RAW-NEXT: 140: 24 80 84 8f lw $4, -32732($gp)
+# RAW-NEXT: 144: 28 80 84 8f lw $4, -32728($gp)
# RAW: SYMBOL TABLE:
# RAW: 00000000 *UND* 00000000
-# RAW: 00002000 l .data 00000000 local
+# RAW: 00002000 l .data 00000000 str1
+# RAW: 00012200 l .data 00000005 str2
+# RAW: 0000012c g F .text 0000001c glob
+# RAW: 00012205 g .data 00000004 hidden
.global glob
.ent glob
glob:
- lw $4,%got(local)($28) # G(local)
- addiu $4,$4,%lo(local) # local (0x2000)
+ lw $4,%got(str1)($28) # G(str1)
+ addiu $4,$4,%lo(str1) # str1
+ lw $4,%got(str2)($28) # G(str2)
+ addiu $4,$4,%lo(str2) # str2
lw $4,%got(hidden)($28) # G(hidden)
lw $4,%call16(glob)($28) # G(glob)
lw $4,%call16(extern)($28) # G(extern)
.end glob
+
.data
- .type local,%object
- .size local,4
-local:
- .word undef
+ .type str1, %object
+ .size str1, 0x10200
+str1:
+ .ascii "str1\000"
+ .space 0x101fb
+
+ .type str2, @object
+ .size str2, 5
+str2:
+ .ascii "str2\000"
.globl hidden
.hidden hidden
More information about the llvm-commits
mailing list