summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2017-10-12 20:03:57 +0000
committerRui Ueyama <ruiu@google.com>2017-10-12 20:03:57 +0000
commit3e8cc2bda689c0d94524e7a7dbc41b09cbf18acb (patch)
treeccdca1bc40222be585f4e4d6d1f44b3150c534f2
parenta7b19157baf498593e8c88797bcc3d3a849645bd (diff)
downloadbcm5719-llvm-3e8cc2bda689c0d94524e7a7dbc41b09cbf18acb.tar.gz
bcm5719-llvm-3e8cc2bda689c0d94524e7a7dbc41b09cbf18acb.zip
Early-continue for a MIPS-specific rule.
This is an attempt to make lld's relocation handler code understandable. Since I don't fully understand what exactly this function does for all possible cases (I believe no one can), I'm not really sure if this patch is NFC, but at least no functionality change intended. All tests still pass. llvm-svn: 315612
-rw-r--r--lld/ELF/Relocations.cpp60
1 files changed, 34 insertions, 26 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index c041399bb27..b3e293d839c 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -80,24 +80,25 @@ static std::string getLocation(InputSectionBase &S, const SymbolBody &Sym,
return Msg + S.getObjMsg<ELFT>(Off);
}
-static bool isPreemptible(const SymbolBody &Body, RelType Type) {
- // In case of MIPS GP-relative relocations always resolve to a definition
- // in a regular input file, ignoring the one-definition rule. So we,
- // for example, should not attempt to create a dynamic relocation even
- // if the target symbol is preemptible. There are two two MIPS GP-relative
- // relocations R_MIPS_GPREL16 and R_MIPS_GPREL32. But only R_MIPS_GPREL16
- // can be against a preemptible symbol.
- // To get MIPS relocation type we apply 0xff mask. In case of O32 ABI all
- // relocation types occupy eight bit. In case of N64 ABI we extract first
- // relocation from 3-in-1 packet because only the first relocation can
- // be against a real symbol.
- if (Config->EMachine == EM_MIPS) {
- Type &= 0xff;
- if (Type == R_MIPS_GPREL16 || Type == R_MICROMIPS_GPREL16 ||
- Type == R_MICROMIPS_GPREL7_S2)
- return false;
- }
- return Body.IsPreemptible;
+// This is a MIPS-specific rule.
+//
+// In case of MIPS GP-relative relocations always resolve to a definition
+// in a regular input file, ignoring the one-definition rule. So we,
+// for example, should not attempt to create a dynamic relocation even
+// if the target symbol is preemptible. There are two two MIPS GP-relative
+// relocations R_MIPS_GPREL16 and R_MIPS_GPREL32. But only R_MIPS_GPREL16
+// can be against a preemptible symbol.
+//
+// To get MIPS relocation type we apply 0xff mask. In case of O32 ABI all
+// relocation types occupy eight bit. In case of N64 ABI we extract first
+// relocation from 3-in-1 packet because only the first relocation can
+// be against a real symbol.
+static bool isMipsGprel(RelType Type) {
+ if (Config->EMachine != EM_MIPS)
+ return false;
+ Type &= 0xff;
+ return Type == R_MIPS_GPREL16 || Type == R_MICROMIPS_GPREL16 ||
+ Type == R_MICROMIPS_GPREL7_S2;
}
// This function is similar to the `handleTlsRelocation`. MIPS does not
@@ -209,13 +210,12 @@ handleTlsRelocation(RelType Type, SymbolBody &Body, InputSectionBase &C,
if (Config->EMachine == EM_MIPS)
return handleMipsTlsRelocation<ELFT>(Type, Body, C, Offset, Addend, Expr);
- bool IsPreemptible = isPreemptible(Body, Type);
if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL>(Expr) &&
Config->Shared) {
if (InX::Got->addDynTlsEntry(Body)) {
uint64_t Off = InX::Got->getGlobalDynOffset(Body);
In<ELFT>::RelaDyn->addReloc(
- {Target->TlsDescRel, InX::Got, Off, !IsPreemptible, &Body, 0});
+ {Target->TlsDescRel, InX::Got, Off, !Body.IsPreemptible, &Body, 0});
}
if (Expr != R_TLSDESC_CALL)
C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
@@ -255,7 +255,7 @@ handleTlsRelocation(RelType Type, SymbolBody &Body, InputSectionBase &C,
// If the symbol is preemptible we need the dynamic linker to write
// the offset too.
uint64_t OffsetOff = Off + Config->Wordsize;
- if (IsPreemptible)
+ if (Body.IsPreemptible)
In<ELFT>::RelaDyn->addReloc(
{Target->TlsOffsetRel, InX::Got, OffsetOff, false, &Body, 0});
else
@@ -268,7 +268,7 @@ handleTlsRelocation(RelType Type, SymbolBody &Body, InputSectionBase &C,
// Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec
// depending on the symbol being locally defined or not.
- if (IsPreemptible) {
+ if (Body.IsPreemptible) {
C.Relocations.push_back(
{Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type,
Offset, Addend, &Body});
@@ -288,7 +288,7 @@ handleTlsRelocation(RelType Type, SymbolBody &Body, InputSectionBase &C,
// Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
// defined.
if (isRelExprOneOf<R_GOT, R_GOT_FROM_END, R_GOT_PC, R_GOT_PAGE_PC>(Expr) &&
- !Config->Shared && !IsPreemptible) {
+ !Config->Shared && !Body.IsPreemptible) {
C.Relocations.push_back(
{R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Body});
return 1;
@@ -377,7 +377,7 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type,
if (E == R_GOT || E == R_PLT || E == R_TLSDESC)
return Target->usesOnlyLowPageBits(Type) || !Config->Pic;
- if (isPreemptible(Body, Type))
+ if (Body.IsPreemptible)
return false;
if (!Config->Pic)
return true;
@@ -858,7 +858,15 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
if (isRelExprOneOf<R_HINT, R_NONE>(Expr))
continue;
- bool Preemptible = isPreemptible(Body, Type);
+ // Handle yet another MIPS-ness.
+ if (isMipsGprel(Type)) {
+ int64_t Addend = computeAddend<ELFT>(Rel, Sec.Data.data()) +
+ computeMipsAddend<ELFT>(Rel, Sec, Expr, Body, End);
+ Sec.Relocations.push_back({R_MIPS_GOTREL, Type, Offset, Addend, &Body});
+ continue;
+ }
+
+ bool Preemptible = Body.IsPreemptible;
// Strenghten or relax a PLT access.
//
@@ -931,7 +939,7 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
}
}
- if (!needsPlt(Expr) && !needsGot(Expr) && isPreemptible(Body, Type)) {
+ if (!needsPlt(Expr) && !needsGot(Expr) && Body.IsPreemptible) {
// We don't know anything about the finaly symbol. Just ask the dynamic
// linker to handle the relocation for us.
if (!Target->isPicRel(Type))
OpenPOWER on IntegriCloud