summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-12-17 01:14:23 +0000
committerRui Ueyama <ruiu@google.com>2015-12-17 01:14:23 +0000
commitbb936067553437ed4dd0de628e173fc5be4d7fa6 (patch)
tree3ee42daa47ac4121f924955ef3dba1d264800351
parent3feddff744316f6801e3640832cb7a8f9f0adfbc (diff)
downloadbcm5719-llvm-bb936067553437ed4dd0de628e173fc5be4d7fa6.tar.gz
bcm5719-llvm-bb936067553437ed4dd0de628e173fc5be4d7fa6.zip
ELF: Separate NeedsCopy and OffsetInBSS.
Previously, OffsetInBSS is -1 if it has no information about copy relocation, 0 if it needs a copy relocation, and >0 if its offset in BSS has been assigned. These flags were too subtle. This patch adds a new flag, NeedsCopy, to carry information about whether a shared symbol needs a copy relocation or not. llvm-svn: 255865
-rw-r--r--lld/ELF/OutputSections.cpp4
-rw-r--r--lld/ELF/Symbols.h7
-rw-r--r--lld/ELF/Writer.cpp6
3 files changed, 9 insertions, 8 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 86780cdc8e6..bb5e0e16111 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -795,7 +795,7 @@ typename ELFFile<ELFT>::uintX_t lld::elf2::getSymVA(const SymbolBody &S) {
return Out<ELFT>::Bss->getVA() + cast<DefinedCommon<ELFT>>(S).OffsetInBSS;
case SymbolBody::SharedKind: {
auto &SS = cast<SharedSymbol<ELFT>>(S);
- if (SS.needsCopy())
+ if (SS.NeedsCopy)
return Out<ELFT>::Bss->getVA() + SS.OffsetInBSS;
return 0;
}
@@ -1323,7 +1323,7 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
OutSec = Out<ELFT>::Bss;
break;
case SymbolBody::SharedKind: {
- if (cast<SharedSymbol<ELFT>>(Body)->needsCopy())
+ if (cast<SharedSymbol<ELFT>>(Body)->NeedsCopy)
OutSec = Out<ELFT>::Bss;
break;
}
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index f51fd2eebf0..34c2d7050f4 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -299,9 +299,10 @@ public:
SharedFile<ELFT> *File;
- // Can have offset if requires copy relocation.
- uintX_t OffsetInBSS = -1;
- bool needsCopy() const { return OffsetInBSS != (uintX_t)-1; }
+ // True if the linker has to generate a copy relocation for this shared
+ // symbol. OffsetInBSS is significant only when NeedsCopy is true.
+ bool NeedsCopy = false;
+ uintX_t OffsetInBSS = 0;
};
// This class represents a symbol defined in an archive file. It is
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index a16eae9f680..cae1f20278d 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -243,10 +243,10 @@ void Writer<ELFT>::scanRelocs(
bool NeedsPlt = false;
if (Body) {
if (auto *E = dyn_cast<SharedSymbol<ELFT>>(Body)) {
- if (E->needsCopy())
+ if (E->NeedsCopy)
continue;
if (Target->relocNeedsCopy(Type, *Body))
- E->OffsetInBSS = 0;
+ E->NeedsCopy = true;
}
NeedsPlt = Target->relocNeedsPlt(Type, *Body);
if (NeedsPlt) {
@@ -712,7 +712,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
if (auto *C = dyn_cast<DefinedCommon<ELFT>>(Body))
CommonSymbols.push_back(C);
if (auto *SC = dyn_cast<SharedSymbol<ELFT>>(Body))
- if (SC->needsCopy())
+ if (SC->NeedsCopy)
SharedCopySymbols.push_back(SC);
if (!includeInSymtab<ELFT>(*Body))
OpenPOWER on IntegriCloud