diff options
author | Rui Ueyama <ruiu@google.com> | 2015-12-17 01:14:23 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2015-12-17 01:14:23 +0000 |
commit | bb936067553437ed4dd0de628e173fc5be4d7fa6 (patch) | |
tree | 3ee42daa47ac4121f924955ef3dba1d264800351 | |
parent | 3feddff744316f6801e3640832cb7a8f9f0adfbc (diff) | |
download | bcm5719-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.cpp | 4 | ||||
-rw-r--r-- | lld/ELF/Symbols.h | 7 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 6 |
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)) |