summaryrefslogtreecommitdiff
path: root/ELF/OutputSections.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ELF/OutputSections.cpp')
-rw-r--r--ELF/OutputSections.cpp93
1 files changed, 23 insertions, 70 deletions
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index dcefd03766d7..d82fdcdc31ba 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -103,7 +103,7 @@ template <class ELFT> void OutputSection::maybeCompress() {
// Write section contents to a temporary buffer and compress it.
std::vector<uint8_t> Buf(Size);
- writeTo<ELFT>(Buf.data());
+ Script->getCmd(this)->writeTo<ELFT>(Buf.data());
if (Error E = zlib::compress(toStringRef(Buf), CompressedData))
fatal("compress failed: " + llvm::toString(std::move(E)));
@@ -112,6 +112,19 @@ template <class ELFT> void OutputSection::maybeCompress() {
Flags |= SHF_COMPRESSED;
}
+template <class ELFT> static void finalizeShtGroup(OutputSection *Sec) {
+ // sh_link field for SHT_GROUP sections should contain the section index of
+ // the symbol table.
+ Sec->Link = InX::SymTab->OutSec->SectionIndex;
+
+ // sh_link then contain index of an entry in symbol table section which
+ // provides signature of the section group.
+ elf::ObjectFile<ELFT> *Obj = Sec->Sections[0]->getFile<ELFT>();
+ assert(Config->Relocatable && Sec->Sections.size() == 1);
+ ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
+ Sec->Info = InX::SymTab->getSymbolIndex(Symbols[Sec->Sections[0]->Info - 1]);
+}
+
template <class ELFT> void OutputSection::finalize() {
if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) {
std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
@@ -126,6 +139,11 @@ template <class ELFT> void OutputSection::finalize() {
}
uint32_t Type = this->Type;
+ if (Type == SHT_GROUP) {
+ finalizeShtGroup<ELFT>(this);
+ return;
+ }
+
if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
return;
@@ -259,69 +277,6 @@ void OutputSection::sortCtorsDtors() {
std::stable_sort(Sections.begin(), Sections.end(), compCtors);
}
-// Fill [Buf, Buf + Size) with Filler.
-// This is used for linker script "=fillexp" command.
-static void fill(uint8_t *Buf, size_t Size, uint32_t Filler) {
- size_t I = 0;
- for (; I + 4 < Size; I += 4)
- memcpy(Buf + I, &Filler, 4);
- memcpy(Buf + I, &Filler, Size - I);
-}
-
-uint32_t OutputSection::getFiller() {
- // Determine what to fill gaps between InputSections with, as specified by the
- // linker script. If nothing is specified and this is an executable section,
- // fall back to trap instructions to prevent bad diassembly and detect invalid
- // jumps to padding.
- if (Optional<uint32_t> Filler = Script->getFiller(this))
- return *Filler;
- if (Flags & SHF_EXECINSTR)
- return Target->TrapInstr;
- return 0;
-}
-
-template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
- Loc = Buf;
-
- // We may have already rendered compressed content when using
- // -compress-debug-sections option. Write it together with header.
- if (!CompressedData.empty()) {
- memcpy(Buf, ZDebugHeader.data(), ZDebugHeader.size());
- memcpy(Buf + ZDebugHeader.size(), CompressedData.data(),
- CompressedData.size());
- return;
- }
-
- // Write leading padding.
- uint32_t Filler = getFiller();
- if (Filler)
- fill(Buf, Sections.empty() ? Size : Sections[0]->OutSecOff, Filler);
-
- parallelForEachN(0, Sections.size(), [=](size_t I) {
- InputSection *Sec = Sections[I];
- Sec->writeTo<ELFT>(Buf);
-
- // Fill gaps between sections.
- if (Filler) {
- uint8_t *Start = Buf + Sec->OutSecOff + Sec->getSize();
- uint8_t *End;
- if (I + 1 == Sections.size())
- End = Buf + Size;
- else
- End = Buf + Sections[I + 1]->OutSecOff;
- fill(Start, End - Start, Filler);
- }
- });
-
- // Linker scripts may have BYTE()-family commands with which you
- // can write arbitrary bytes to the output. Process them if any.
- Script->writeDataBytes(this, Buf);
-}
-
-static uint64_t getOutFlags(InputSectionBase *S) {
- return S->Flags & ~SHF_GROUP & ~SHF_COMPRESSED;
-}
-
static SectionKey createKey(InputSectionBase *C, StringRef OutsecName) {
// The ELF spec just says
// ----------------------------------------------------------------
@@ -418,7 +373,10 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS,
return;
}
- uint64_t Flags = getOutFlags(IS);
+ uint64_t Flags = IS->Flags;
+ if (!Config->Relocatable)
+ Flags &= ~(uint64_t)SHF_GROUP;
+
if (Sec) {
if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
error("incompatible section flags for " + Sec->Name +
@@ -484,8 +442,3 @@ template void OutputSection::maybeCompress<ELF32LE>();
template void OutputSection::maybeCompress<ELF32BE>();
template void OutputSection::maybeCompress<ELF64LE>();
template void OutputSection::maybeCompress<ELF64BE>();
-
-template void OutputSection::writeTo<ELF32LE>(uint8_t *Buf);
-template void OutputSection::writeTo<ELF32BE>(uint8_t *Buf);
-template void OutputSection::writeTo<ELF64LE>(uint8_t *Buf);
-template void OutputSection::writeTo<ELF64BE>(uint8_t *Buf);