[lld] r286053 - Rewrite CommonInputSection as a synthetic input section.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 5 16:05:47 PDT 2016
Author: ruiu
Date: Sat Nov 5 18:05:47 2016
New Revision: 286053
URL: http://llvm.org/viewvc/llvm-project?rev=286053&view=rev
Log:
Rewrite CommonInputSection as a synthetic input section.
A CommonInputSection is a section containing all common symbols.
That was an input section but was abstracted in a different way
than the synthetic input sections because it was written before
the synthetic input section was invented.
This patch rewrites CommonInputSection as a synthetic input section
so that it behaves better with other sections.
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/InputSection.h
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Writer.cpp
lld/trunk/test/ELF/linkerscript/double-bss.s
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Sat Nov 5 18:05:47 2016
@@ -825,31 +825,6 @@ bool MipsAbiFlagsInputSection<ELFT>::cla
return S->kind() == InputSectionBase<ELFT>::MipsAbiFlags;
}
-template <class ELFT>
-InputSection<ELFT> InputSection<ELFT>::createCommonInputSection(
- std::vector<DefinedCommon *> Syms) {
- // Sort the common symbols by alignment as an heuristic to pack them better.
- std::stable_sort(Syms.begin(), Syms.end(),
- [](const DefinedCommon *A, const DefinedCommon *B) {
- return A->Alignment > B->Alignment;
- });
-
- size_t Size = 0;
- uintX_t Alignment = 1;
- for (DefinedCommon *Sym : Syms) {
- Alignment = std::max<uintX_t>(Alignment, Sym->Alignment);
- Size = alignTo(Size, Sym->Alignment);
-
- // Compute symbol offset relative to beginning of input section.
- Sym->Offset = Size;
- Size += Sym->Size;
- }
- ArrayRef<uint8_t> Data = makeArrayRef<uint8_t>(nullptr, Size);
- InputSection Ret(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Data, "");
- Ret.Live = true;
- return Ret;
-}
-
template class elf::InputSectionBase<ELF32LE>;
template class elf::InputSectionBase<ELF32BE>;
template class elf::InputSectionBase<ELF64LE>;
Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Sat Nov 5 18:05:47 2016
@@ -273,14 +273,6 @@ public:
template <class RelTy>
void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
- // Common symbols don't belong to any section. But it is easier for us
- // to handle them as if they belong to some input section. So we defined
- // this section that "contains" all common symbols.
- static InputSection<ELFT> *CommonInputSection;
-
- static InputSection<ELFT>
- createCommonInputSection(std::vector<DefinedCommon *> Syms);
-
private:
template <class RelTy>
void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
@@ -294,9 +286,6 @@ private:
llvm::TinyPtrVector<const Thunk<ELFT> *> Thunks;
};
-template <class ELFT>
-InputSection<ELFT> *InputSection<ELFT>::CommonInputSection;
-
// MIPS .reginfo section provides information on the registers used by the code
// in the object file. Linker should collect this information and write a single
// .reginfo section in the output file. The output section contains a union of
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Sat Nov 5 18:05:47 2016
@@ -202,13 +202,9 @@ void LinkerScript<ELFT>::computeInputSec
if (elf::ObjectFile<ELFT> *F = S->getFile())
Filename = sys::path::filename(F->getName());
- if (!I->FilePat.match(Filename) || Pat.ExcludedFilePat.match(Filename))
- continue;
-
- if (Pat.SectionPat.match(S->Name))
+ if (I->FilePat.match(Filename) && !Pat.ExcludedFilePat.match(Filename) &&
+ Pat.SectionPat.match(S->Name))
I->Sections.push_back(S);
- if (Pat.SectionPat.match("COMMON"))
- I->Sections.push_back(InputSection<ELFT>::CommonInputSection);
}
// Sort sections as instructed by SORT-family commands and --sort-section
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Sat Nov 5 18:05:47 2016
@@ -15,6 +15,7 @@
#include "Memory.h"
#include "Strings.h"
#include "SymbolTable.h"
+#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Core/Parallel.h"
#include "llvm/Support/Dwarf.h"
@@ -1556,7 +1557,7 @@ SymbolTableSection<ELFT>::getOutputSecti
break;
}
case SymbolBody::DefinedCommonKind:
- return InputSection<ELFT>::CommonInputSection->OutSec;
+ return In<ELFT>::Common->OutSec;
case SymbolBody::SharedKind:
if (cast<SharedSymbol<ELFT>>(Sym)->needsCopy())
return Out<ELFT>::Bss;
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Sat Nov 5 18:05:47 2016
@@ -12,6 +12,7 @@
#include "InputFiles.h"
#include "InputSection.h"
#include "OutputSections.h"
+#include "SyntheticSections.h"
#include "Target.h"
#include "llvm/ADT/STLExtras.h"
@@ -69,8 +70,7 @@ static typename ELFT::uint getSymVA(cons
return VA;
}
case SymbolBody::DefinedCommonKind:
- return InputSection<ELFT>::CommonInputSection->OutSec->getVA() +
- InputSection<ELFT>::CommonInputSection->OutSecOff +
+ return In<ELFT>::Common->OutSec->getVA() + In<ELFT>::Common->OutSecOff +
cast<DefinedCommon>(Body).Offset;
case SymbolBody::SharedKind: {
auto &SS = cast<SharedSymbol<ELFT>>(Body);
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Sat Nov 5 18:05:47 2016
@@ -21,6 +21,7 @@
#include "Memory.h"
#include "OutputSections.h"
#include "Strings.h"
+#include "SymbolTable.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/MD5.h"
@@ -37,6 +38,43 @@ using namespace llvm::support::endian;
using namespace lld;
using namespace lld::elf;
+template <class ELFT> static std::vector<DefinedCommon *> getCommonSymbols() {
+ std::vector<DefinedCommon *> V;
+ for (Symbol *S : Symtab<ELFT>::X->getSymbols())
+ if (auto *B = dyn_cast<DefinedCommon>(S->body()))
+ V.push_back(B);
+ return V;
+}
+
+// Find all common symbols and allocate space for them.
+template <class ELFT>
+CommonSection<ELFT>::CommonSection()
+ : InputSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 1,
+ ArrayRef<uint8_t>(), "COMMON") {
+ this->Live = true;
+
+ // Sort the common symbols by alignment as an heuristic to pack them better.
+ std::vector<DefinedCommon *> Syms = getCommonSymbols<ELFT>();
+ std::stable_sort(Syms.begin(), Syms.end(),
+ [](const DefinedCommon *A, const DefinedCommon *B) {
+ return A->Alignment > B->Alignment;
+ });
+
+ // Assign offsets to symbols.
+ size_t Size = 0;
+ size_t Alignment = 1;
+ for (DefinedCommon *Sym : Syms) {
+ Alignment = std::max(Alignment, Sym->Alignment);
+ Size = alignTo(Size, Sym->Alignment);
+
+ // Compute symbol offset relative to beginning of input section.
+ Sym->Offset = Size;
+ Size += Sym->Size;
+ }
+ this->Alignment = Alignment;
+ this->Data = makeArrayRef<uint8_t>(nullptr, Size);
+}
+
static ArrayRef<uint8_t> createInterp() {
// StringSaver guarantees that the returned string ends with '\0'.
StringRef S = Saver.save(Config->DynamicLinker);
@@ -111,6 +149,11 @@ void BuildIdHexstring<ELFT>::writeBuildI
Config->BuildIdVector.size());
}
+template class elf::CommonSection<ELF32LE>;
+template class elf::CommonSection<ELF32BE>;
+template class elf::CommonSection<ELF64LE>;
+template class elf::CommonSection<ELF64BE>;
+
template class elf::InterpSection<ELF32LE>;
template class elf::InterpSection<ELF32BE>;
template class elf::InterpSection<ELF64LE>;
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Sat Nov 5 18:05:47 2016
@@ -15,11 +15,19 @@
namespace lld {
namespace elf {
+// This class represents a BSS section containing all common symbols.
+template <class ELFT> class CommonSection final : public InputSection<ELFT> {
+public:
+ CommonSection();
+};
+
+// .interp section.
template <class ELFT> class InterpSection final : public InputSection<ELFT> {
public:
InterpSection();
};
+// .note.gnu.build-id section.
template <class ELFT> class BuildIdSection : public InputSection<ELFT> {
public:
virtual void writeBuildId(llvm::MutableArrayRef<uint8_t> Buf) = 0;
@@ -67,13 +75,13 @@ public:
// Linker generated sections which can be used as inputs.
template <class ELFT> struct In {
static BuildIdSection<ELFT> *BuildId;
+ static CommonSection<ELFT> *Common;
static InterpSection<ELFT> *Interp;
- static std::vector<InputSection<ELFT> *> Sections;
};
template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
+template <class ELFT> CommonSection<ELFT> *In<ELFT>::Common;
template <class ELFT> InterpSection<ELFT> *In<ELFT>::Interp;
-template <class ELFT> std::vector<InputSection<ELFT> *> In<ELFT>::Sections;
} // namespace elf
} // namespace lld
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Sat Nov 5 18:05:47 2016
@@ -105,6 +105,11 @@ StringRef elf::getOutputSectionName(Stri
return Prefix;
}
+ // CommonSection is identified as "COMMON" in linker scripts.
+ // By default, it should go to .bss section.
+ if (Name == "COMMON")
+ return ".bss";
+
// ".zdebug_" is a prefix for ZLIB-compressed sections.
// Because we decompressed input sections, we want to remove 'z'.
if (Name.startswith(".zdebug_"))
@@ -130,14 +135,6 @@ template <class ELFT> void elf::writeRes
Writer<ELFT>().run();
}
-template <class ELFT> static std::vector<DefinedCommon *> getCommonSymbols() {
- std::vector<DefinedCommon *> V;
- for (Symbol *S : Symtab<ELFT>::X->getSymbols())
- if (auto *B = dyn_cast<DefinedCommon>(S->body()))
- V.push_back(B);
- return V;
-}
-
// The main function of the writer.
template <class ELFT> void Writer<ELFT>::run() {
createSyntheticSections();
@@ -146,10 +143,6 @@ template <class ELFT> void Writer<ELFT>:
if (Target->NeedsThunks)
forEachRelSec(createThunks<ELFT>);
- InputSection<ELFT> Common =
- InputSection<ELFT>::createCommonInputSection(getCommonSymbols<ELFT>());
- InputSection<ELFT>::CommonInputSection = &Common;
-
Script<ELFT>::X->OutputSections = &OutputSections;
if (ScriptConfig->HasSections) {
Script<ELFT>::X->createSections(Factory);
@@ -234,8 +227,12 @@ template <class ELFT> void Writer<ELFT>:
Out<ELFT>::ProgramHeaders = make<OutputSectionBase<ELFT>>("", 0, SHF_ALLOC);
Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t));
- if (needsInterpSection<ELFT>())
+ if (needsInterpSection<ELFT>()) {
In<ELFT>::Interp = make<InterpSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Interp);
+ } else {
+ In<ELFT>::Interp = nullptr;
+ }
if (!Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic) {
Out<ELFT>::DynSymTab =
@@ -284,8 +281,17 @@ template <class ELFT> void Writer<ELFT>:
In<ELFT>::BuildId = make<BuildIdUuid<ELFT>>();
else if (Config->BuildId == BuildIdKind::Hexstring)
In<ELFT>::BuildId = make<BuildIdHexstring<ELFT>>();
+ else
+ In<ELFT>::BuildId = nullptr;
- In<ELFT>::Sections = {In<ELFT>::BuildId, In<ELFT>::Interp};
+ if (In<ELFT>::BuildId)
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::BuildId);
+
+ CommonSection<ELFT> *Common = make<CommonSection<ELFT>>();
+ if (!Common->Data.empty()) {
+ In<ELFT>::Common = Common;
+ Symtab<ELFT>::X->Sections.push_back(Common);
+ }
}
template <class ELFT>
@@ -803,22 +809,10 @@ template <class ELFT> void Writer<ELFT>:
if (HasError)
return;
- // If linker script processor hasn't added common symbol section yet,
- // then add it to .bss now.
- if (!InputSection<ELFT>::CommonInputSection->OutSec) {
- Out<ELFT>::Bss->addSection(InputSection<ELFT>::CommonInputSection);
- Out<ELFT>::Bss->assignOffsets();
- }
-
// So far we have added sections from input object files.
// This function adds linker-created Out<ELFT>::* sections.
addPredefinedSections();
- // Adds linker generated input sections to
- // corresponding output sections.
- for (InputSection<ELFT> *S : In<ELFT>::Sections)
- addInputSec(S);
-
sortSections();
unsigned I = 1;
@@ -827,11 +821,6 @@ template <class ELFT> void Writer<ELFT>:
Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
}
- // Finalize linker generated sections.
- for (InputSection<ELFT> *S : In<ELFT>::Sections)
- if (S && S->OutSec)
- S->OutSec->assignOffsets();
-
// Finalizers fix each section's size.
// .dynsym is finalized early since that may fill up .gnu.hash.
if (Out<ELFT>::DynSymTab)
Modified: lld/trunk/test/ELF/linkerscript/double-bss.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/double-bss.s?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/double-bss.s (original)
+++ lld/trunk/test/ELF/linkerscript/double-bss.s Sat Nov 5 18:05:47 2016
@@ -1,10 +1,15 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
-# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text*) } }" > %t.script
+# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; " > %t.script
+# RUN: echo ".text : { *(.text*) }" >> %t.script
+# RUN: echo ".bss1 : { *(.bss) }" >> %t.script
+# RUN: echo ".bss2 : { *(COMMON) }" >> %t.script
+# RUN: echo "}" >> %t.script
+
# RUN: ld.lld -o %t1 --script %t.script %t
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
-# CHECK: .bss 00000004 0000000000000122 BSS
-# CHECK-NEXT: .bss 00000080 0000000000000128 BSS
+# CHECK: .bss1 00000004 0000000000000122 BSS
+# CHECK-NEXT: .bss2 00000080 0000000000000128 BSS
.globl _start
_start:
More information about the llvm-commits
mailing list