[PATCH] D15480: [ELF][MIPS] Handle R_MIPS_HI16/LO16 relocations against _gp_disp symbol
Simon Atanasyan via llvm-commits
llvm-commits at lists.llvm.org
Sat Dec 12 22:54:38 PST 2015
atanasyan created this revision.
atanasyan added reviewers: ruiu, rafael.
atanasyan added a subscriber: llvm-commits.
atanasyan set the repository for this revision to rL LLVM.
atanasyan added a project: lld.
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.
I put code which adjust symbol value in case of `R_MIPS_HI16/LO16` relocations into the `InputSectionBase<ELFT>::relocate` routine to escape passing `SymboBody` to each `relocateOne` methods while it is necessary for MIPS target only.
It is possible to optimize the current solution a bit. We can save a reference to the `SymbolBody` instance created by the `addIgnoredSym` call and replace "_gp_disp" string comparison by comparison of `SymbolBody` references. But I cannot find a good place to keep the reference to the "_gp_disp" `SymbolBody`.
Repository:
rL LLVM
http://reviews.llvm.org/D15480
Files:
ELF/Driver.cpp
ELF/InputSection.cpp
test/ELF/mips-hilo-gp-disp.s
Index: test/ELF/mips-hilo-gp-disp.s
===================================================================
--- /dev/null
+++ test/ELF/mips-hilo-gp-disp.s
@@ -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
Index: ELF/InputSection.cpp
===================================================================
--- ELF/InputSection.cpp
+++ ELF/InputSection.cpp
@@ -205,6 +205,11 @@
} else if (Target->isTlsDynReloc(Type) ||
Target->isSizeDynReloc(Type, Body)) {
continue;
+ } else if (Config->EMachine == EM_MIPS) {
+ if (Type == R_MIPS_HI16 && Body.getName() == "_gp_disp")
+ SymVA = getMipsGpAddr<ELFT>() - AddrLoc;
+ else if (Type == R_MIPS_LO16 && Body.getName() == "_gp_disp")
+ SymVA = getMipsGpAddr<ELFT>() - AddrLoc + 4;
}
uintX_t A = getAddend<ELFT>(RI);
uintX_t Size = getSymSize<ELFT>(Body);
Index: ELF/Driver.cpp
===================================================================
--- ELF/Driver.cpp
+++ ELF/Driver.cpp
@@ -263,6 +263,11 @@
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)
+ Symtab.addIgnoredSym("_gp_disp");
+
if (!Config->Entry.empty()) {
// Set either EntryAddr (if S is a number) or EntrySym (otherwise).
StringRef S = Config->Entry;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15480.42650.patch
Type: text/x-patch
Size: 2945 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151213/d71acc0d/attachment.bin>
More information about the llvm-commits
mailing list