summaryrefslogtreecommitdiff
path: root/ELF/InputSection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ELF/InputSection.cpp')
-rw-r--r--ELF/InputSection.cpp31
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;