[lld] r255768 - [ELF][MIPS] Handle R_MIPS_HI16/LO16 relocations against _gp_disp symbol
Simon Atanasyan via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 16 06:45:10 PST 2015
Author: atanasyan
Date: Wed Dec 16 08:45:09 2015
New Revision: 255768
URL: http://llvm.org/viewvc/llvm-project?rev=255768&view=rev
Log:
[ELF][MIPS] Handle R_MIPS_HI16/LO16 relocations against _gp_disp symbol
The `_gp_disp` is a magic symbol designates offset between start of
function and gp pointer into GOT. Only `R_MIPS_HI16` and `R_MIPS_LO16`
relocations are permitted with `_gp_disp`. The patch adds the `_gp_disp`
as an ignored symbol and adjusts symbol value before call the `relocateOne`
for `R_MIPS_HI16/LO16` relocations.
Differential Revision: http://reviews.llvm.org/D15480
Added:
lld/trunk/test/ELF/mips-hilo-gp-disp.s
Modified:
lld/trunk/ELF/Config.h
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/SymbolTable.h
Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=255768&r1=255767&r2=255768&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Dec 16 08:45:09 2015
@@ -32,6 +32,7 @@ enum ELFKind {
struct Configuration {
SymbolBody *EntrySym = nullptr;
+ SymbolBody *MipsGpDisp = nullptr;
InputFile *FirstElf = nullptr;
llvm::StringRef DynamicLinker;
llvm::StringRef Entry;
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=255768&r1=255767&r2=255768&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Dec 16 08:45:09 2015
@@ -263,6 +263,11 @@ template <class ELFT> void LinkerDriver:
Symtab.addIgnoredSym("_GLOBAL_OFFSET_TABLE_");
}
+ // On MIPS O32 ABI _gp_disp is a magic symbol designates offset between
+ // start of function and gp pointer into GOT.
+ if (Config->EMachine == EM_MIPS)
+ Config->MipsGpDisp = Symtab.addIgnoredSym("_gp_disp");
+
if (!Config->Entry.empty()) {
// Set either EntryAddr (if S is a number) or EntrySym (otherwise).
StringRef S = Config->Entry;
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=255768&r1=255767&r2=255768&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Dec 16 08:45:09 2015
@@ -205,6 +205,11 @@ void InputSectionBase<ELFT>::relocate(ui
} else if (Target->isTlsDynReloc(Type) ||
Target->isSizeDynReloc(Type, Body)) {
continue;
+ } else if (Config->EMachine == EM_MIPS) {
+ if (Type == R_MIPS_HI16 && &Body == Config->MipsGpDisp)
+ SymVA = getMipsGpAddr<ELFT>() - AddrLoc;
+ else if (Type == R_MIPS_LO16 && &Body == Config->MipsGpDisp)
+ SymVA = getMipsGpAddr<ELFT>() - AddrLoc + 4;
}
uintX_t A = getAddend<ELFT>(RI);
uintX_t Size = getSymSize<ELFT>(Body);
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=255768&r1=255767&r2=255768&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed Dec 16 08:45:09 2015
@@ -88,10 +88,12 @@ void SymbolTable<ELFT>::addSyntheticSym(
resolve(Sym);
}
-template <class ELFT> void SymbolTable<ELFT>::addIgnoredSym(StringRef Name) {
+template <class ELFT>
+SymbolBody *SymbolTable<ELFT>::addIgnoredSym(StringRef Name) {
auto Sym = new (Alloc)
DefinedAbsolute<ELFT>(Name, DefinedAbsolute<ELFT>::IgnoreUndef);
resolve(Sym);
+ return Sym;
}
template <class ELFT> bool SymbolTable<ELFT>::isUndefined(StringRef Name) {
Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=255768&r1=255767&r2=255768&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Wed Dec 16 08:45:09 2015
@@ -54,7 +54,7 @@ public:
typename llvm::object::ELFFile<ELFT>::Elf_Sym &ESym);
void addSyntheticSym(StringRef Name, OutputSectionBase<ELFT> &Section,
typename llvm::object::ELFFile<ELFT>::uintX_t Value);
- void addIgnoredSym(StringRef Name);
+ SymbolBody *addIgnoredSym(StringRef Name);
bool isUndefined(StringRef Name);
void scanShlibUndefined();
SymbolBody *find(StringRef Name);
Added: lld/trunk/test/ELF/mips-hilo-gp-disp.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-hilo-gp-disp.s?rev=255768&view=auto
==============================================================================
--- lld/trunk/test/ELF/mips-hilo-gp-disp.s (added)
+++ lld/trunk/test/ELF/mips-hilo-gp-disp.s Wed Dec 16 08:45:09 2015
@@ -0,0 +1,42 @@
+# Check R_MIPS_HI16 / LO16 relocations calculation against _gp_disp.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: %S/Inputs/mips-dynamic.s -o %t2.o
+# RUN: ld.lld %t1.o %t2.o -o %t.exe
+# RUN: llvm-objdump -d -t %t.exe | FileCheck -check-prefix=EXE %s
+# RUN: ld.lld %t1.o %t2.o -shared -o %t.so
+# RUN: llvm-objdump -d -t %t.so | FileCheck -check-prefix=SO %s
+
+# REQUIRES: mips
+
+ .text
+ .globl __start
+__start:
+ lui $t0,%hi(_gp_disp)
+ addi $t0,$t0,%lo(_gp_disp)
+ lw $v0,%call16(_foo)($gp)
+
+# EXE: Disassembly of section .text:
+# EXE-NEXT: __start:
+# EXE-NEXT: 20000: 3c 08 00 01 lui $8, 1
+# ^-- %hi(0x37ff0-0x20000)
+# EXE-NEXT: 20004: 21 08 7f f0 addi $8, $8, 32752
+# ^-- %lo(0x37ff0-0x20004+4)
+
+# EXE: SYMBOL TABLE:
+# EXE: 00037ff0 *ABS* 00000000 _gp
+# EXE: 00020000 .text 00000000 __start
+# EXE: 00020010 .text 00000000 _foo
+
+# SO: Disassembly of section .text:
+# SO-NEXT: __start:
+# SO-NEXT: 10000: 3c 08 00 01 lui $8, 1
+# ^-- %hi(0x27ff0-0x10000)
+# SO-NEXT: 10004: 21 08 7f f0 addi $8, $8, 32752
+# ^-- %lo(0x27ff0-0x10004+4)
+
+# SO: SYMBOL TABLE:
+# SO: 00027ff0 *ABS* 00000000 _gp
+# SO: 00010000 .text 00000000 __start
+# SO: 00010010 .text 00000000 _foo
More information about the llvm-commits
mailing list