summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Writer.cpp')
-rw-r--r--lld/ELF/Writer.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 708e29049fb..d1604a27679 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -674,17 +674,22 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
if (needsPlt(Expr) || Expr == R_THUNK || refersToGotEntry(Expr) ||
!Body.isPreemptible()) {
- // If the relocation points to something in the file, remember it so that
- // we can apply it when writting the section.
- C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
+ // If the relocation points to something in the file, we can process it.
+ bool Constant = isStaticLinkTimeConstant<ELFT>(Expr, Type, Body);
// If the output being produced is position independent, the final value
// is still not known. In that case we still need some help from the
// dynamic linker. We can however do better than just copying the incoming
// relocation. We can process some of it and and just ask the dynamic
// linker to add the load address.
- if (!isStaticLinkTimeConstant<ELFT>(Expr, Type, Body))
+ if (!Constant)
AddDyn({Target->RelativeRel, C.OutSec, Offset, true, &Body, Addend});
+
+ // If the produced value is a constant, we just remember to write it
+ // when outputting this section. We also have to do it if the format
+ // uses Elf_Rel, since in that case the written value is the addend.
+ if (Constant || !RelTy::IsRela)
+ C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
} else {
// We don't know anything about the finaly symbol. Just ask the dynamic
// linker to handle the relocation for us.
OpenPOWER on IntegriCloud