[ELF][MIPS] Implement R_MIPS_GPREL16/R_MIPS_GPREL32 relocations
The R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations use the following
expressions for calculations:
```
local symbol: S + A + GP0 - GP
global symbol: S + A - GP
GP - Represents the final gp value, i.e. _gp symbol
GP0 - Represents the gp value used to create the relocatable object
```
The GP0 value is taken from the .reginfo data section defined by an object
file. To implement that I keep a reference to `MipsReginfoInputSection`
in the `ObjectFile` class. This reference is used by the
`ObjectFile::getMipsGp0` method to return the GP0 value.
Differential Revision: http://reviews.llvm.org/D15760
llvm-svn: 256416
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index a68d836..e0827a3 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -93,6 +93,10 @@
return this->getSymbolsHelper(true);
}
+template <class ELFT> uint32_t ObjectFile<ELFT>::getMipsGp0() const {
+ return MipsReginfo ? MipsReginfo->getGp0() : 0;
+}
+
template <class ELFT>
const typename ObjectFile<ELFT>::Elf_Sym *
ObjectFile<ELFT>::getLocalSymbol(uintX_t SymIndex) {
@@ -245,8 +249,10 @@
// A MIPS object file has a special section that contains register
// usage info, which needs to be handled by the linker specially.
- if (Config->EMachine == EM_MIPS && Name == ".reginfo")
- return new (this->Alloc) MipsReginfoInputSection<ELFT>(this, &Sec);
+ if (Config->EMachine == EM_MIPS && Name == ".reginfo") {
+ MipsReginfo = new (this->Alloc) MipsReginfoInputSection<ELFT>(this, &Sec);
+ return MipsReginfo;
+ }
if (Name == ".eh_frame")
return new (this->EHAlloc.Allocate()) EHInputSection<ELFT>(this, &Sec);