forked from OSchip/llvm-project
[ELF] Simpler scheme for handling common symbols
Convert all common symbols to regular symbols after scan. This means that the downstream code does not to handle common symbols as a special case. Differential Revision: https://reviews.llvm.org/D38137 llvm-svn: 314495
This commit is contained in:
parent
6150419d71
commit
73eabf23a4
|
@ -1086,6 +1086,14 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
|||
if (!Config->Relocatable)
|
||||
InputSections.push_back(createCommentSection<ELFT>());
|
||||
|
||||
// Create a .bss section for each common symbol and then replace the common
|
||||
// symbol with a DefinedRegular symbol. As a result, all common symbols are
|
||||
// "instantiated" as regular defined symbols, so that we don't need to care
|
||||
// about common symbols beyond this point. Note that if -r is given, we just
|
||||
// need to pass through common symbols as-is.
|
||||
if (Config->DefineCommon)
|
||||
createCommonSections<ELFT>();
|
||||
|
||||
// Do size optimizations: garbage collection, merging of SHF_MERGE sections
|
||||
// and identical code folding.
|
||||
if (Config->GcSections)
|
||||
|
|
|
@ -64,11 +64,6 @@ static void resolveReloc(InputSectionBase &Sec, RelT &Rel,
|
|||
std::function<void(InputSectionBase *, uint64_t)> Fn) {
|
||||
SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
|
||||
|
||||
if (auto *Sym = dyn_cast<DefinedCommon>(&B)) {
|
||||
Sym->Live = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto *D = dyn_cast<DefinedRegular>(&B)) {
|
||||
if (!D->Section)
|
||||
return;
|
||||
|
@ -223,13 +218,9 @@ template <class ELFT> void elf::markLive() {
|
|||
};
|
||||
|
||||
auto MarkSymbol = [&](SymbolBody *Sym) {
|
||||
if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym)) {
|
||||
if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym))
|
||||
if (auto *IS = cast_or_null<InputSectionBase>(D->Section))
|
||||
Enqueue(IS, D->Value);
|
||||
return;
|
||||
}
|
||||
if (auto *S = dyn_cast_or_null<DefinedCommon>(Sym))
|
||||
S->Live = true;
|
||||
};
|
||||
|
||||
// Add GC root symbols.
|
||||
|
|
|
@ -99,14 +99,8 @@ static uint64_t getSymVA(const SymbolBody &Body, int64_t &Addend) {
|
|||
}
|
||||
return VA;
|
||||
}
|
||||
case SymbolBody::DefinedCommonKind: {
|
||||
if (!Config->DefineCommon)
|
||||
return 0;
|
||||
auto DC = cast<DefinedCommon>(Body);
|
||||
if (!DC.Live)
|
||||
return 0;
|
||||
return DC.Section->getParent()->Addr + DC.Section->OutSecOff;
|
||||
}
|
||||
case SymbolBody::DefinedCommonKind:
|
||||
llvm_unreachable("common are converted to bss");
|
||||
case SymbolBody::SharedKind: {
|
||||
auto &SS = cast<SharedSymbol>(Body);
|
||||
if (SS.CopyRelSec)
|
||||
|
@ -286,7 +280,7 @@ DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint32_t Alignment,
|
|||
uint8_t StOther, uint8_t Type)
|
||||
: Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther,
|
||||
Type),
|
||||
Live(!Config->GcSections), Alignment(Alignment), Size(Size) {}
|
||||
Alignment(Alignment), Size(Size) {}
|
||||
|
||||
// If a shared symbol is referred via a copy relocation, its alignment
|
||||
// becomes part of the ABI. This function returns a symbol alignment.
|
||||
|
|
|
@ -167,11 +167,6 @@ public:
|
|||
return S->kind() == SymbolBody::DefinedCommonKind;
|
||||
}
|
||||
|
||||
// True if this symbol is not GC'ed. Liveness is usually a notion of
|
||||
// input sections and not of symbols, but since common symbols don't
|
||||
// belong to any input section, their liveness is managed by this bit.
|
||||
bool Live;
|
||||
|
||||
// The maximum alignment we have seen for this symbol.
|
||||
uint32_t Alignment;
|
||||
|
||||
|
|
|
@ -54,24 +54,28 @@ uint64_t SyntheticSection::getVA() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
std::vector<InputSection *> elf::createCommonSections() {
|
||||
if (!Config->DefineCommon)
|
||||
return {};
|
||||
|
||||
std::vector<InputSection *> Ret;
|
||||
// Create a .bss section for each common section and replace the common symbol
|
||||
// with a DefinedRegular symbol.
|
||||
template <class ELFT> void elf::createCommonSections() {
|
||||
for (Symbol *S : Symtab->getSymbols()) {
|
||||
auto *Sym = dyn_cast<DefinedCommon>(S->body());
|
||||
if (!Sym || !Sym->Live)
|
||||
|
||||
if (!Sym)
|
||||
continue;
|
||||
|
||||
Sym->Section = make<BssSection>("COMMON");
|
||||
size_t Pos = Sym->Section->reserveSpace(Sym->Size, Sym->Alignment);
|
||||
assert(Pos == 0);
|
||||
(void)Pos;
|
||||
Sym->Section->File = Sym->getFile();
|
||||
Ret.push_back(Sym->Section);
|
||||
// Create a synthetic section for the common data.
|
||||
auto *Section = make<BssSection>("COMMON");
|
||||
Section->File = Sym->getFile();
|
||||
Section->Live = !Config->GcSections;
|
||||
Section->reserveSpace(Sym->Size, Sym->Alignment);
|
||||
InputSections.push_back(Section);
|
||||
|
||||
// Replace all DefinedCommon symbols with DefinedRegular symbols so that we
|
||||
// don't have to care about DefinedCommon symbols beyond this point.
|
||||
replaceBody<DefinedRegular>(S, Sym->getFile(), Sym->getName(),
|
||||
static_cast<bool>(Sym->IsLocal), Sym->StOther,
|
||||
Sym->Type, 0, Sym->getSize<ELFT>(), Section);
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
// Returns an LLD version string.
|
||||
|
@ -2378,6 +2382,11 @@ template void PltSection::addEntry<ELF32BE>(SymbolBody &Sym);
|
|||
template void PltSection::addEntry<ELF64LE>(SymbolBody &Sym);
|
||||
template void PltSection::addEntry<ELF64BE>(SymbolBody &Sym);
|
||||
|
||||
template void elf::createCommonSections<ELF32LE>();
|
||||
template void elf::createCommonSections<ELF32BE>();
|
||||
template void elf::createCommonSections<ELF64LE>();
|
||||
template void elf::createCommonSections<ELF64BE>();
|
||||
|
||||
template MergeInputSection *elf::createCommentSection<ELF32LE>();
|
||||
template MergeInputSection *elf::createCommentSection<ELF32BE>();
|
||||
template MergeInputSection *elf::createCommentSection<ELF64LE>();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -786,7 +786,7 @@ private:
|
|||
size_t Size = 0;
|
||||
};
|
||||
|
||||
std::vector<InputSection *> createCommonSections();
|
||||
template <class ELFT> void createCommonSections();
|
||||
InputSection *createInterpSection();
|
||||
template <class ELFT> MergeInputSection *createCommentSection();
|
||||
void decompressAndMergeSections();
|
||||
|
|
|
@ -290,9 +290,6 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
|
|||
Add(InX::BuildId);
|
||||
}
|
||||
|
||||
for (InputSection *S : createCommonSections())
|
||||
Add(S);
|
||||
|
||||
InX::Bss = make<BssSection>(".bss");
|
||||
Add(InX::Bss);
|
||||
InX::BssRelRo = make<BssSection>(".bss.rel.ro");
|
||||
|
@ -441,11 +438,7 @@ static bool includeInSymtab(const SymbolBody &B) {
|
|||
if (auto *S = dyn_cast<MergeInputSection>(Sec))
|
||||
if (!S->getSectionPiece(D->Value)->Live)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto *Sym = dyn_cast<DefinedCommon>(&B))
|
||||
return Sym->Live;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue