summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2017-10-13 01:19:10 +0000
committerRui Ueyama <ruiu@google.com>2017-10-13 01:19:10 +0000
commit17819c8bbb0f9874a0b30812645d3411d8ae9c17 (patch)
tree87228d2a5e34798138035972f6f531a162500815
parent51823d3aaecda36b89788e59e861d1b7566c4348 (diff)
downloadbcm5719-llvm-17819c8bbb0f9874a0b30812645d3411d8ae9c17.tar.gz
bcm5719-llvm-17819c8bbb0f9874a0b30812645d3411d8ae9c17.zip
Slightly simplify code and add comment.
This is not a mechanical transformation. Even though I believe this patch is correct, I'm not 100% sure if lld with this patch behaves exactly the same way as before on all edge cases. At least all tests still pass. I'm submitting this patch because it took almost a day to understand this function, and I don't want to lose it. llvm-svn: 315658
-rw-r--r--lld/ELF/Relocations.cpp26
1 files changed, 22 insertions, 4 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 65a4e267c30..ef9e0d03bb7 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -815,13 +815,31 @@ static void addGotEntry(SymbolBody &Sym, bool Preemptible) {
DynType = Target->GotRel;
}
- bool Constant = !Preemptible && (!Config->Pic || isAbsolute(Sym));
- if (!Constant)
+ // If a GOT slot value can be calculated at link-time, which is now,
+ // we can just fill that out.
+ //
+ // (We don't actually write a value to a GOT slot right now, but we
+ // add a static relocation to a Relocations vector so that
+ // InputSection::relocate will do the work for us. We may be able
+ // to just write a value now, but it is a TODO.)
+ bool IsLinkTimeConstant = !Preemptible && (!Config->Pic || isAbsolute(Sym));
+ if (IsLinkTimeConstant) {
+ InX::Got->Relocations.push_back({Expr, DynType, Off, 0, &Sym});
+ } else {
+ // Otherwise, we emit a dynamic relocation to .rel[a].dyn so that
+ // the GOT slot will be fixed at load-time.
In<ELFT>::RelaDyn->addReloc(
{DynType, InX::Got, Off, !Preemptible, &Sym, 0});
- if (Constant || (!Config->IsRela && !Preemptible))
- InX::Got->Relocations.push_back({Expr, DynType, Off, 0, &Sym});
+ // REL type relocations don't have addend fields unlike RELAs, and
+ // their addends are stored to the section to which they are applied.
+ // So, store addends if we need to.
+ //
+ // This is ugly -- the difference between REL and RELA should be
+ // handled in a better way. It's a TODO.
+ if (!Config->IsRela)
+ InX::Got->Relocations.push_back({R_ABS, Target->GotRel, Off, 0, &Sym});
+ }
}
// The reason we have to do this early scan is as follows
OpenPOWER on IntegriCloud