diff options
Diffstat (limited to 'ELF/OutputSections.cpp')
| -rw-r--r-- | ELF/OutputSections.cpp | 93 | 
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);  | 
