diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-29 16:26:20 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-29 16:26:20 +0000 | 
| commit | bef2946c219dc621608bcc9e47f8b973e5ef5c70 (patch) | |
| tree | 1e4dfae199fc27167ed7496693938fec2dab65c2 /ELF/InputSection.cpp | |
| parent | c53addf38e24e4dafe992aafb3ae928bfa8fdb0a (diff) | |
Notes
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;  | 
