[lld] r298817 - Remove MIPS-specific code from computeAddend.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 26 12:35:25 PDT 2017
Author: ruiu
Date: Sun Mar 26 14:35:24 2017
New Revision: 298817
URL: http://llvm.org/viewvc/llvm-project?rev=298817&view=rev
Log:
Remove MIPS-specific code from computeAddend.
Previously, computeAddend had many parameters but most of them were
used only for MIPS. The MIPS ABI is too odd that I don't want to mix
it into the regular code path. Splitting the function into non-MIPS
and MIPS parts makes the regular code path easy to follow.
Modified:
lld/trunk/ELF/Relocations.cpp
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=298817&r1=298816&r2=298817&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Sun Mar 26 14:35:24 2017
@@ -237,9 +237,8 @@ handleTlsRelocation(uint32_t Type, Symbo
return 0;
}
-template <class RelTy>
-static uint32_t getMipsPairType(const RelTy *Rel, const SymbolBody &Sym) {
- switch (Rel->getType(Config->IsMips64EL)) {
+static uint32_t getMipsPairType(uint32_t Type, const SymbolBody &Sym) {
+ switch (Type) {
case R_MIPS_HI16:
return R_MIPS_LO16;
case R_MIPS_GOT16:
@@ -253,37 +252,6 @@ static uint32_t getMipsPairType(const Re
}
}
-template <class RelTy>
-static int32_t findMipsPairedAddend(const uint8_t *Buf, const uint8_t *BufLoc,
- SymbolBody &Sym, const RelTy *Rel,
- const RelTy *End) {
- uint32_t SymIndex = Rel->getSymbol(Config->IsMips64EL);
- uint32_t Type = getMipsPairType(Rel, Sym);
-
- // Some MIPS relocations use addend calculated from addend of the relocation
- // itself and addend of paired relocation. ABI requires to compute such
- // combined addend in case of REL relocation record format only.
- // See p. 4-17 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- if (RelTy::IsRela || Type == R_MIPS_NONE)
- return 0;
-
- for (const RelTy *RI = Rel; RI != End; ++RI) {
- if (RI->getType(Config->IsMips64EL) != Type)
- continue;
- if (RI->getSymbol(Config->IsMips64EL) != SymIndex)
- continue;
-
- endianness E = Config->Endianness;
- int32_t Hi = (read32(BufLoc, E) & 0xffff) << 16;
- int32_t Lo = SignExtend32<16>(read32(Buf + RI->r_offset, E));
- return Hi + Lo;
- }
-
- warn("can't find matching " + toString(Type) + " relocation for " +
- toString(Rel->getType(Config->IsMips64EL)));
- return 0;
-}
-
// True if non-preemptable symbol always has the same value regardless of where
// the DSO is loaded.
static bool isAbsolute(const SymbolBody &Body) {
@@ -581,26 +549,62 @@ static RelExpr adjustExpr(SymbolBody &Bo
return Expr;
}
+// Returns an addend of a given relocation. If it is RELA, an addend
+// is in a relocation itself. If it is REL, we need to read it from an
+// input section.
template <class ELFT, class RelTy>
-static int64_t computeAddend(const elf::ObjectFile<ELFT> &File,
- const uint8_t *SectionData, const RelTy *End,
- const RelTy &Rel, RelExpr Expr, SymbolBody &Body) {
+static int64_t computeAddend(const RelTy &Rel, const uint8_t *Buf) {
+ int64_t A = getAddend<ELFT>(Rel);
uint32_t Type = Rel.getType(Config->IsMips64EL);
- int64_t Addend = getAddend<ELFT>(Rel);
- const uint8_t *BufLoc = SectionData + Rel.r_offset;
if (!RelTy::IsRela)
- Addend += Target->getImplicitAddend(BufLoc, Type);
+ A += Target->getImplicitAddend(Buf + Rel.r_offset, Type);
+ if (Config->EMachine == EM_PPC64 && Config->Pic && Type == R_PPC64_TOC)
+ A += getPPC64TocBase();
+ return A;
+}
- if (Config->EMachine == EM_MIPS) {
- Addend += findMipsPairedAddend(SectionData, BufLoc, Body, &Rel, End);
- if (Expr == R_MIPS_GOTREL && Body.isLocal())
- Addend += File.MipsGp0;
+// MIPS has an odd notion of "paired" relocations to calculate addends.
+// For example, if a relocation is of R_MIPS_HI16, there must be a
+// R_MIPS_LO16 relocation after that, and an addend is calculated using
+// the two relocations.
+template <class ELFT, class RelTy>
+static int64_t computeMipsAddend(const RelTy &Rel, InputSectionBase &Sec,
+ RelExpr Expr, SymbolBody &Body,
+ const RelTy *End) {
+ if (Expr == R_MIPS_GOTREL && Body.isLocal())
+ return Sec.getFile<ELFT>()->MipsGp0;
+
+ // The ABI says that the paired relocation is used only for REL.
+ // See p. 4-17 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+ if (RelTy::IsRela)
+ return 0;
+
+ uint32_t Type = Rel.getType(Config->IsMips64EL);
+ uint32_t PairTy = getMipsPairType(Type, Body);
+ if (PairTy == R_MIPS_NONE)
+ return 0;
+
+ const uint8_t *Buf = Sec.Data.data();
+ uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
+
+ // To make things worse, paired relocations might not be contiguous in
+ // the relocation table, so we need to do linear search. *sigh*
+ for (const RelTy *RI = &Rel; RI != End; ++RI) {
+ if (RI->getType(Config->IsMips64EL) != PairTy)
+ continue;
+ if (RI->getSymbol(Config->IsMips64EL) != SymIndex)
+ continue;
+
+ endianness E = Config->Endianness;
+ int32_t Hi = (read32(Buf + Rel.r_offset, E) & 0xffff) << 16;
+ int32_t Lo = SignExtend32<16>(read32(Buf + RI->r_offset, E));
+ return Hi + Lo;
}
- if (Config->Pic && Config->EMachine == EM_PPC64 && Type == R_PPC64_TOC)
- Addend += getPPC64TocBase();
- return Addend;
+ warn("can't find matching " + toString(PairTy) + " relocation for " +
+ toString(Type));
+ return 0;
}
template <class ELFT>
@@ -719,7 +723,7 @@ template <class ELFT, class RelTy>
static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
OffsetGetter GetOffset(Sec);
- for (auto I = Rels.begin(), E = Rels.end(); I != E; ++I) {
+ for (auto I = Rels.begin(), End = Rels.end(); I != End; ++I) {
const RelTy &Rel = *I;
SymbolBody &Body = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
uint32_t Type = Rel.getType(Config->IsMips64EL);
@@ -727,7 +731,7 @@ static void scanRelocs(InputSectionBase
if (Config->MipsN32Abi) {
uint32_t Processed;
std::tie(Type, Processed) =
- mergeMipsN32RelTypes(Type, Rel.r_offset, I + 1, E);
+ mergeMipsN32RelTypes(Type, Rel.r_offset, I + 1, End);
I += Processed;
}
@@ -761,8 +765,9 @@ static void scanRelocs(InputSectionBase
R_GOTREL_FROM_END, R_PPC_TOC>(Expr))
In<ELFT>::Got->HasGotOffRel = true;
- int64_t Addend = computeAddend(*Sec.getFile<ELFT>(), Sec.Data.data(), E,
- Rel, Expr, Body);
+ int64_t Addend = computeAddend<ELFT>(Rel, Sec.Data.data());
+ if (Config->EMachine == EM_MIPS)
+ Addend += computeMipsAddend<ELFT>(Rel, Sec, Expr, Body, End);
if (unsigned Processed =
handleTlsRelocation<ELFT>(Type, Body, Sec, Offset, Addend, Expr)) {
More information about the llvm-commits
mailing list