summaryrefslogtreecommitdiffstats
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r--lld/ELF/OutputSections.cpp50
1 files changed, 24 insertions, 26 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 2056d1966b9..1bc6e6bd99d 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -104,12 +104,6 @@ RelocationSection<ELFT>::RelocationSection(SymbolTableSection<ELFT> &DynSymSec,
this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
}
-static bool isLocalDefinition(const SymbolBody *Body) {
- if (!Body)
- return true;
- return !Body->isShared() && !Body->isUndefined();
-}
-
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
bool IsMips64EL = Relocs[0].C.getFile()->getObj().isMips64EL();
@@ -126,32 +120,36 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
const ELFFile<ELFT> &Obj = File.getObj();
uint32_t Type = RI.getType(IsMips64EL);
+
+ bool CanBePreempted = canBePreempted(Body);
+ uintX_t Addend = 0;
+ if (!CanBePreempted) {
+ if (IsRela) {
+ if (Body)
+ Addend += getSymVA(cast<ELFSymbolBody<ELFT>>(*Body), BssSec);
+ else
+ Addend += getLocalSymVA(
+ Obj.getRelocationSymbol(&RI, File.getSymbolTable()), File);
+ }
+ P->setSymbolAndType(0, Target->getRelativeReloc(), IsMips64EL);
+ }
+
if (Body && Target->relocNeedsGot(Type, *Body)) {
P->r_offset = GotSec.getEntryAddr(*Body);
- P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
- Target->getGotReloc(), IsMips64EL);
+ if (CanBePreempted)
+ P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
+ Target->getGotReloc(), IsMips64EL);
} else {
- P->r_offset = RI.r_offset + C.getOutputSectionOff() + Out->getVA();
- uintX_t Addend = 0;
if (IsRela)
- Addend = static_cast<const Elf_Rela &>(RI).r_addend;
-
- if (!isLocalDefinition(Body)) {
+ Addend += static_cast<const Elf_Rela &>(RI).r_addend;
+ P->r_offset = RI.r_offset + C.getOutputSectionOff() + Out->getVA();
+ if (CanBePreempted)
P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Type,
IsMips64EL);
- } else {
- P->setSymbolAndType(0, Target->getRelativeReloc(), IsMips64EL);
- if (IsRela) {
- if (Body)
- Addend += getSymVA(cast<ELFSymbolBody<ELFT>>(*Body), BssSec);
- else
- Addend += getLocalSymVA(
- Obj.getRelocationSymbol(&RI, File.getSymbolTable()), File);
- }
- }
- if (IsRela)
- static_cast<Elf_Rela *>(P)->r_addend = Addend;
}
+
+ if (IsRela)
+ static_cast<Elf_Rela *>(P)->r_addend = Addend;
}
}
@@ -418,7 +416,7 @@ bool lld::elf2::canBePreempted(const SymbolBody *Body) {
return true;
if (!Config->Shared)
return false;
- return true;
+ return Body->getMostConstrainingVisibility() == STV_DEFAULT;
}
template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
OpenPOWER on IntegriCloud