[lld] r263381 - [ELF][MIPS] Factor out SumVA adjustments into a couple of separate functions. NFC.
Simon Atanasyan via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 13 08:37:40 PDT 2016
Author: atanasyan
Date: Sun Mar 13 10:37:38 2016
New Revision: 263381
URL: http://llvm.org/viewvc/llvm-project?rev=263381&view=rev
Log:
[ELF][MIPS] Factor out SumVA adjustments into a couple of separate functions. NFC.
The patch does not reduce the size of the code but makes
InputSectionBase::relocate cleaner a bit.
Differential Revision: http://reviews.llvm.org/D18119
Modified:
lld/trunk/ELF/InputSection.cpp
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=263381&r1=263380&r2=263381&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Sun Mar 13 10:37:38 2016
@@ -176,6 +176,49 @@ uint8_t *InputSectionBase<ELFT>::findMip
return nullptr;
}
+template <class ELFT, class uintX_t>
+static uintX_t adjustMipsSymVA(uint32_t Type, const ObjectFile<ELFT> &File,
+ const SymbolBody &Body, uintX_t AddrLoc,
+ uintX_t SymVA) {
+ if (Type == R_MIPS_HI16 && &Body == Config->MipsGpDisp)
+ return getMipsGpAddr<ELFT>() - AddrLoc;
+ if (Type == R_MIPS_LO16 && &Body == Config->MipsGpDisp)
+ return getMipsGpAddr<ELFT>() - AddrLoc + 4;
+ if (&Body == Config->MipsLocalGp)
+ return getMipsGpAddr<ELFT>();
+ if (Body.isLocal() && (Type == R_MIPS_GPREL16 || Type == R_MIPS_GPREL32))
+ // We need to adjust SymVA value in case of R_MIPS_GPREL16/32
+ // relocations because they use the following expression to calculate
+ // the relocation's result for local symbol: S + A + GP0 - G.
+ return SymVA + File.getMipsGp0();
+ return SymVA;
+}
+
+template <class ELFT, class uintX_t>
+static uintX_t getMipsGotVA(const SymbolBody &Body, uintX_t SymVA,
+ uint8_t *BufLoc, uint8_t *PairedLoc) {
+ if (Body.isLocal()) {
+ // If relocation against MIPS local symbol requires GOT entry, this entry
+ // should be initialized by 'page address'. This address is high 16-bits
+ // of sum the symbol's value and the addend. The addend in that case is
+ // calculated using addends from R_MIPS_GOT16 and paired R_MIPS_LO16
+ // relocations.
+ const endianness E = ELFT::TargetEndianness;
+ uint64_t AHL = read32<E>(BufLoc) << 16;
+ if (PairedLoc)
+ AHL += SignExtend64<16>(read32<E>(PairedLoc));
+ return Out<ELFT>::Got->getMipsLocalPageAddr(SymVA + AHL);
+ }
+ if (!canBePreempted(Body))
+ // For non-local symbols GOT entries should contain their full
+ // addresses. But if such symbol cannot be preempted, we do not
+ // have to put them into the "global" part of GOT and use dynamic
+ // linker to determine their actual addresses. That is why we
+ // create GOT entries for them in the "local" part of GOT.
+ return Out<ELFT>::Got->getMipsLocalFullAddr(Body);
+ return Body.getGotVA<ELFT>();
+}
+
template <class ELFT>
template <class RelTy>
void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd,
@@ -239,29 +282,10 @@ void InputSectionBase<ELFT>::relocate(ui
if (Target->needsPlt<ELFT>(Type, Body)) {
SymVA = Body.getPltVA<ELFT>() + A;
} else if (Target->needsGot(Type, Body)) {
- if (Config->EMachine == EM_MIPS && !CBP) {
- if (Body.isLocal()) {
- // R_MIPS_GOT16 relocation against local symbol requires index of
- // a local GOT entry which contains page address corresponds
- // to sum of the symbol address and addend. The addend in that case
- // is calculated using addends from R_MIPS_GOT16 and paired
- // R_MIPS_LO16 relocations.
- const endianness E = ELFT::TargetEndianness;
- uint64_t AHL = read32<E>(BufLoc) << 16;
- if (PairedLoc)
- AHL += SignExtend64<16>(read32<E>(PairedLoc));
- SymVA = Out<ELFT>::Got->getMipsLocalPageAddr(SymVA + AHL);
- } else {
- // For non-local symbols GOT entries should contain their full
- // addresses. But if such symbol cannot be preempted, we do not
- // have to put them into the "global" part of GOT and use dynamic
- // linker to determine their actual addresses. That is why we
- // create GOT entries for them in the "local" part of GOT.
- SymVA = Out<ELFT>::Got->getMipsLocalFullAddr(Body) + A;
- }
- } else {
+ if (Config->EMachine == EM_MIPS)
+ SymVA = getMipsGotVA<ELFT>(Body, SymVA, BufLoc, PairedLoc) + A;
+ else
SymVA = Body.getGotVA<ELFT>() + A;
- }
if (Body.IsTls)
Type = Target->getTlsGotRel(Type);
} else if (Target->isSizeRel(Type) && CBP) {
@@ -271,18 +295,7 @@ void InputSectionBase<ELFT>::relocate(ui
// with a possibly incorrect value.
continue;
} else if (Config->EMachine == EM_MIPS) {
- if (Type == R_MIPS_HI16 && &Body == Config->MipsGpDisp) {
- SymVA = getMipsGpAddr<ELFT>() - AddrLoc + A;
- } else if (Type == R_MIPS_LO16 && &Body == Config->MipsGpDisp) {
- SymVA = getMipsGpAddr<ELFT>() - AddrLoc + 4 + A;
- } else if (&Body == Config->MipsLocalGp) {
- SymVA = getMipsGpAddr<ELFT>() + A;
- } else if (Type == R_MIPS_GPREL16 || Type == R_MIPS_GPREL32) {
- // We need to adjust SymVA value in case of R_MIPS_GPREL16/32
- // relocations because they use the following expression to calculate
- // the relocation's result for local symbol: S + A + GP0 - G.
- SymVA += File->getMipsGp0();
- }
+ SymVA = adjustMipsSymVA<ELFT>(Type, *File, Body, AddrLoc, SymVA) + A;
} else if (!Target->needsCopyRel<ELFT>(Type, Body) && CBP) {
continue;
}
More information about the llvm-commits
mailing list