diff options
Diffstat (limited to 'ELF/InputSection.cpp')
-rw-r--r-- | ELF/InputSection.cpp | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp index e8cfd21c4c49..466656efbf08 100644 --- a/ELF/InputSection.cpp +++ b/ELF/InputSection.cpp @@ -23,6 +23,7 @@ #include "llvm/Support/Compression.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Path.h" +#include "llvm/Support/Threading.h" #include <mutex> using namespace llvm; @@ -172,7 +173,8 @@ void InputSectionBase::uncompress() { if (Error E = Dec.decompress({OutputBuf, Size})) fatal(toString(this) + ": decompress failed: " + llvm::toString(std::move(E))); - Data = ArrayRef<uint8_t>((uint8_t *)OutputBuf, Size); + this->Data = ArrayRef<uint8_t>((uint8_t *)OutputBuf, Size); + this->Flags &= ~(uint64_t)SHF_COMPRESSED; } uint64_t SectionBase::getOffset(const DefinedRegular &Sym) const { @@ -293,6 +295,24 @@ bool InputSectionBase::classof(const SectionBase *S) { return S->kind() != Output; } +void InputSection::copyShtGroup(uint8_t *Buf) { + assert(this->Type == SHT_GROUP); + + ArrayRef<uint32_t> From = getDataAs<uint32_t>(); + uint32_t *To = reinterpret_cast<uint32_t *>(Buf); + + // First entry is a flag word, we leave it unchanged. + *To++ = From[0]; + + // Here we adjust indices of sections that belong to group as it + // might change during linking. + ArrayRef<InputSectionBase *> Sections = this->File->getSections(); + for (uint32_t Val : From.slice(1)) { + uint32_t Index = read32(&Val, Config->Endianness); + write32(To++, Sections[Index]->OutSec->SectionIndex, Config->Endianness); + } +} + InputSectionBase *InputSection::getRelocatedSection() { assert(this->Type == SHT_RELA || this->Type == SHT_REL); ArrayRef<InputSectionBase *> Sections = this->File->getSections(); @@ -678,6 +698,13 @@ template <class ELFT> void InputSection::writeTo(uint8_t *Buf) { return; } + // If -r is given, linker should keep SHT_GROUP sections. We should fixup + // them, see copyShtGroup(). + if (this->Type == SHT_GROUP) { + copyShtGroup(Buf + OutSecOff); + return; + } + // Copy section contents from source object file to output file // and then apply relocations. memcpy(Buf + OutSecOff, Data.data(), Data.size()); @@ -866,7 +893,7 @@ const SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) const { // it is not just an addition to a base output offset. uint64_t MergeInputSection::getOffset(uint64_t Offset) const { // Initialize OffsetMap lazily. - std::call_once(InitOffsetMap, [&] { + llvm::call_once(InitOffsetMap, [&] { OffsetMap.reserve(Pieces.size()); for (const SectionPiece &Piece : Pieces) OffsetMap[Piece.InputOff] = Piece.OutputOff; |