Convert BuildIdSection to input section
Differential revision: https://reviews.llvm.org/D25627 llvm-svn: 285682
This commit is contained in:
parent
e70fa63390
commit
282251a226
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "llvm/Support/Compression.h"
|
#include "llvm/Support/Compression.h"
|
||||||
#include "llvm/Support/Endian.h"
|
#include "llvm/Support/Endian.h"
|
||||||
|
#include "llvm/Support/RandomNumberGenerator.h"
|
||||||
|
#include "llvm/Support/xxhash.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
|
@ -480,6 +482,9 @@ template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||||
if (this->Type == SHT_NOBITS)
|
if (this->Type == SHT_NOBITS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Set output location.
|
||||||
|
this->OutputLoc = Buf + OutSecOff;
|
||||||
|
|
||||||
// If -r is given, then an InputSection may be a relocation section.
|
// If -r is given, then an InputSection may be a relocation section.
|
||||||
if (this->Type == SHT_RELA) {
|
if (this->Type == SHT_RELA) {
|
||||||
copyRelocations(Buf + OutSecOff, this->template getDataAs<Elf_Rela>());
|
copyRelocations(Buf + OutSecOff, this->template getDataAs<Elf_Rela>());
|
||||||
|
@ -848,6 +853,60 @@ InputSection<ELFT> InputSection<ELFT>::createCommonInputSection(
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
BuildIdSection<ELFT>::BuildIdSection(size_t HashSize)
|
||||||
|
: InputSection<ELFT>(SHF_ALLOC, SHT_NOTE, 1, ArrayRef<uint8_t>(),
|
||||||
|
".note.gnu.build-id") {
|
||||||
|
Buf.resize(16 + HashSize);
|
||||||
|
const endianness E = ELFT::TargetEndianness;
|
||||||
|
write32<E>(Buf.data(), 4); // Name size
|
||||||
|
write32<E>(Buf.data() + 4, HashSize); // Content size
|
||||||
|
write32<E>(Buf.data() + 8, NT_GNU_BUILD_ID); // Type
|
||||||
|
memcpy(Buf.data() + 12, "GNU", 4); // Name string
|
||||||
|
this->Data = ArrayRef<uint8_t>(Buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
void BuildIdFastHash<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
|
||||||
|
const endianness E = ELFT::TargetEndianness;
|
||||||
|
|
||||||
|
// 64-bit xxhash
|
||||||
|
uint64_t Hash = xxHash64(toStringRef(Buf));
|
||||||
|
write64<E>(this->OutputLoc + 16, Hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
void BuildIdMd5<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
|
||||||
|
MD5 Hash;
|
||||||
|
Hash.update(Buf);
|
||||||
|
MD5::MD5Result Res;
|
||||||
|
Hash.final(Res);
|
||||||
|
memcpy(this->OutputLoc + 16, Res, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
void BuildIdSha1<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
|
||||||
|
SHA1 Hash;
|
||||||
|
Hash.update(Buf);
|
||||||
|
memcpy(this->OutputLoc + 16, Hash.final().data(), 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
void BuildIdUuid<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
|
||||||
|
if (getRandomBytes(this->OutputLoc + 16, 16))
|
||||||
|
error("entropy source failure");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
BuildIdHexstring<ELFT>::BuildIdHexstring()
|
||||||
|
: BuildIdSection<ELFT>(Config->BuildIdVector.size()) {}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
void BuildIdHexstring<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
|
||||||
|
memcpy(this->OutputLoc + 16, Config->BuildIdVector.data(),
|
||||||
|
Config->BuildIdVector.size());
|
||||||
|
}
|
||||||
|
|
||||||
template class elf::InputSectionBase<ELF32LE>;
|
template class elf::InputSectionBase<ELF32LE>;
|
||||||
template class elf::InputSectionBase<ELF32BE>;
|
template class elf::InputSectionBase<ELF32BE>;
|
||||||
template class elf::InputSectionBase<ELF64LE>;
|
template class elf::InputSectionBase<ELF64LE>;
|
||||||
|
@ -882,3 +941,33 @@ template class elf::MipsAbiFlagsInputSection<ELF32LE>;
|
||||||
template class elf::MipsAbiFlagsInputSection<ELF32BE>;
|
template class elf::MipsAbiFlagsInputSection<ELF32BE>;
|
||||||
template class elf::MipsAbiFlagsInputSection<ELF64LE>;
|
template class elf::MipsAbiFlagsInputSection<ELF64LE>;
|
||||||
template class elf::MipsAbiFlagsInputSection<ELF64BE>;
|
template class elf::MipsAbiFlagsInputSection<ELF64BE>;
|
||||||
|
|
||||||
|
template class elf::BuildIdSection<ELF32LE>;
|
||||||
|
template class elf::BuildIdSection<ELF32BE>;
|
||||||
|
template class elf::BuildIdSection<ELF64LE>;
|
||||||
|
template class elf::BuildIdSection<ELF64BE>;
|
||||||
|
|
||||||
|
template class elf::BuildIdFastHash<ELF32LE>;
|
||||||
|
template class elf::BuildIdFastHash<ELF32BE>;
|
||||||
|
template class elf::BuildIdFastHash<ELF64LE>;
|
||||||
|
template class elf::BuildIdFastHash<ELF64BE>;
|
||||||
|
|
||||||
|
template class elf::BuildIdMd5<ELF32LE>;
|
||||||
|
template class elf::BuildIdMd5<ELF32BE>;
|
||||||
|
template class elf::BuildIdMd5<ELF64LE>;
|
||||||
|
template class elf::BuildIdMd5<ELF64BE>;
|
||||||
|
|
||||||
|
template class elf::BuildIdSha1<ELF32LE>;
|
||||||
|
template class elf::BuildIdSha1<ELF32BE>;
|
||||||
|
template class elf::BuildIdSha1<ELF64LE>;
|
||||||
|
template class elf::BuildIdSha1<ELF64BE>;
|
||||||
|
|
||||||
|
template class elf::BuildIdUuid<ELF32LE>;
|
||||||
|
template class elf::BuildIdUuid<ELF32BE>;
|
||||||
|
template class elf::BuildIdUuid<ELF64LE>;
|
||||||
|
template class elf::BuildIdUuid<ELF64BE>;
|
||||||
|
|
||||||
|
template class elf::BuildIdHexstring<ELF32LE>;
|
||||||
|
template class elf::BuildIdHexstring<ELF32BE>;
|
||||||
|
template class elf::BuildIdHexstring<ELF64LE>;
|
||||||
|
template class elf::BuildIdHexstring<ELF64BE>;
|
||||||
|
|
|
@ -252,6 +252,9 @@ public:
|
||||||
// to. The writer sets a value.
|
// to. The writer sets a value.
|
||||||
uint64_t OutSecOff = 0;
|
uint64_t OutSecOff = 0;
|
||||||
|
|
||||||
|
// Location of this section in the output buffer
|
||||||
|
uint8_t *OutputLoc = nullptr;
|
||||||
|
|
||||||
// InputSection that is dependent on us (reverse dependency for GC)
|
// InputSection that is dependent on us (reverse dependency for GC)
|
||||||
InputSectionBase<ELFT> *DependentSection = nullptr;
|
InputSectionBase<ELFT> *DependentSection = nullptr;
|
||||||
|
|
||||||
|
@ -339,6 +342,58 @@ public:
|
||||||
const llvm::object::Elf_Mips_ABIFlags<ELFT> *Flags = nullptr;
|
const llvm::object::Elf_Mips_ABIFlags<ELFT> *Flags = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class ELFT> class BuildIdSection : public InputSection<ELFT> {
|
||||||
|
typedef OutputSectionBase<ELFT> Base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void writeBuildId(ArrayRef<uint8_t> Buf) = 0;
|
||||||
|
virtual ~BuildIdSection() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BuildIdSection(size_t HashSize);
|
||||||
|
std::vector<uint8_t> Buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
class BuildIdFastHash final : public BuildIdSection<ELFT> {
|
||||||
|
public:
|
||||||
|
BuildIdFastHash() : BuildIdSection<ELFT>(8) {}
|
||||||
|
void writeBuildId(ArrayRef<uint8_t> Buf) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class ELFT> class BuildIdMd5 final : public BuildIdSection<ELFT> {
|
||||||
|
public:
|
||||||
|
BuildIdMd5() : BuildIdSection<ELFT>(16) {}
|
||||||
|
void writeBuildId(ArrayRef<uint8_t> Buf) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class ELFT> class BuildIdSha1 final : public BuildIdSection<ELFT> {
|
||||||
|
public:
|
||||||
|
BuildIdSha1() : BuildIdSection<ELFT>(20) {}
|
||||||
|
void writeBuildId(ArrayRef<uint8_t> Buf) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class ELFT> class BuildIdUuid final : public BuildIdSection<ELFT> {
|
||||||
|
public:
|
||||||
|
BuildIdUuid() : BuildIdSection<ELFT>(16) {}
|
||||||
|
void writeBuildId(ArrayRef<uint8_t> Buf) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
class BuildIdHexstring final : public BuildIdSection<ELFT> {
|
||||||
|
public:
|
||||||
|
BuildIdHexstring();
|
||||||
|
void writeBuildId(ArrayRef<uint8_t>) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Linker generated sections which can be used as inputs.
|
||||||
|
template <class ELFT> struct In {
|
||||||
|
static BuildIdSection<ELFT> *BuildId;
|
||||||
|
static std::vector<InputSection<ELFT> *> Sections;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
|
||||||
|
template <class ELFT> std::vector<InputSection<ELFT> *> In<ELFT>::Sections;
|
||||||
} // namespace elf
|
} // namespace elf
|
||||||
} // namespace lld
|
} // namespace lld
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,7 @@
|
||||||
#include "llvm/Support/Dwarf.h"
|
#include "llvm/Support/Dwarf.h"
|
||||||
#include "llvm/Support/MD5.h"
|
#include "llvm/Support/MD5.h"
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Support/RandomNumberGenerator.h"
|
|
||||||
#include "llvm/Support/SHA1.h"
|
#include "llvm/Support/SHA1.h"
|
||||||
#include "llvm/Support/xxhash.h"
|
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::dwarf;
|
using namespace llvm::dwarf;
|
||||||
|
@ -1738,64 +1736,6 @@ template <class ELFT> void VersionNeedSection<ELFT>::finalize() {
|
||||||
this->Header.sh_size = Size;
|
this->Header.sh_size = Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
BuildIdSection<ELFT>::BuildIdSection(size_t HashSize)
|
|
||||||
: OutputSectionBase<ELFT>(".note.gnu.build-id", SHT_NOTE, SHF_ALLOC),
|
|
||||||
HashSize(HashSize) {
|
|
||||||
// 16 bytes for the note section header.
|
|
||||||
this->Header.sh_size = 16 + HashSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT> void BuildIdSection<ELFT>::writeTo(uint8_t *Buf) {
|
|
||||||
const endianness E = ELFT::TargetEndianness;
|
|
||||||
write32<E>(Buf, 4); // Name size
|
|
||||||
write32<E>(Buf + 4, HashSize); // Content size
|
|
||||||
write32<E>(Buf + 8, NT_GNU_BUILD_ID); // Type
|
|
||||||
memcpy(Buf + 12, "GNU", 4); // Name string
|
|
||||||
HashBuf = Buf + 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
void BuildIdFastHash<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
|
|
||||||
const endianness E = ELFT::TargetEndianness;
|
|
||||||
|
|
||||||
// 64-bit xxhash
|
|
||||||
uint64_t Hash = xxHash64(toStringRef(Buf));
|
|
||||||
write64<E>(this->HashBuf, Hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
void BuildIdMd5<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
|
|
||||||
MD5 Hash;
|
|
||||||
Hash.update(Buf);
|
|
||||||
MD5::MD5Result Res;
|
|
||||||
Hash.final(Res);
|
|
||||||
memcpy(this->HashBuf, Res, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
void BuildIdSha1<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
|
|
||||||
SHA1 Hash;
|
|
||||||
Hash.update(Buf);
|
|
||||||
memcpy(this->HashBuf, Hash.final().data(), 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
void BuildIdUuid<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
|
|
||||||
if (getRandomBytes(this->HashBuf, 16))
|
|
||||||
error("entropy source failure");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
BuildIdHexstring<ELFT>::BuildIdHexstring()
|
|
||||||
: BuildIdSection<ELFT>(Config->BuildIdVector.size()) {}
|
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
void BuildIdHexstring<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
|
|
||||||
memcpy(this->HashBuf, Config->BuildIdVector.data(),
|
|
||||||
Config->BuildIdVector.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
MipsReginfoOutputSection<ELFT>::MipsReginfoOutputSection()
|
MipsReginfoOutputSection<ELFT>::MipsReginfoOutputSection()
|
||||||
: OutputSectionBase<ELFT>(".reginfo", SHT_MIPS_REGINFO, SHF_ALLOC) {
|
: OutputSectionBase<ELFT>(".reginfo", SHT_MIPS_REGINFO, SHF_ALLOC) {
|
||||||
|
@ -2101,36 +2041,6 @@ template class VersionDefinitionSection<ELF32BE>;
|
||||||
template class VersionDefinitionSection<ELF64LE>;
|
template class VersionDefinitionSection<ELF64LE>;
|
||||||
template class VersionDefinitionSection<ELF64BE>;
|
template class VersionDefinitionSection<ELF64BE>;
|
||||||
|
|
||||||
template class BuildIdSection<ELF32LE>;
|
|
||||||
template class BuildIdSection<ELF32BE>;
|
|
||||||
template class BuildIdSection<ELF64LE>;
|
|
||||||
template class BuildIdSection<ELF64BE>;
|
|
||||||
|
|
||||||
template class BuildIdFastHash<ELF32LE>;
|
|
||||||
template class BuildIdFastHash<ELF32BE>;
|
|
||||||
template class BuildIdFastHash<ELF64LE>;
|
|
||||||
template class BuildIdFastHash<ELF64BE>;
|
|
||||||
|
|
||||||
template class BuildIdMd5<ELF32LE>;
|
|
||||||
template class BuildIdMd5<ELF32BE>;
|
|
||||||
template class BuildIdMd5<ELF64LE>;
|
|
||||||
template class BuildIdMd5<ELF64BE>;
|
|
||||||
|
|
||||||
template class BuildIdSha1<ELF32LE>;
|
|
||||||
template class BuildIdSha1<ELF32BE>;
|
|
||||||
template class BuildIdSha1<ELF64LE>;
|
|
||||||
template class BuildIdSha1<ELF64BE>;
|
|
||||||
|
|
||||||
template class BuildIdUuid<ELF32LE>;
|
|
||||||
template class BuildIdUuid<ELF32BE>;
|
|
||||||
template class BuildIdUuid<ELF64LE>;
|
|
||||||
template class BuildIdUuid<ELF64BE>;
|
|
||||||
|
|
||||||
template class BuildIdHexstring<ELF32LE>;
|
|
||||||
template class BuildIdHexstring<ELF32BE>;
|
|
||||||
template class BuildIdHexstring<ELF64LE>;
|
|
||||||
template class BuildIdHexstring<ELF64BE>;
|
|
||||||
|
|
||||||
template class GdbIndexSection<ELF32LE>;
|
template class GdbIndexSection<ELF32LE>;
|
||||||
template class GdbIndexSection<ELF32BE>;
|
template class GdbIndexSection<ELF32BE>;
|
||||||
template class GdbIndexSection<ELF64LE>;
|
template class GdbIndexSection<ELF64LE>;
|
||||||
|
|
|
@ -51,7 +51,6 @@ public:
|
||||||
typedef typename ELFT::Shdr Elf_Shdr;
|
typedef typename ELFT::Shdr Elf_Shdr;
|
||||||
enum Kind {
|
enum Kind {
|
||||||
Base,
|
Base,
|
||||||
BuildId,
|
|
||||||
Dynamic,
|
Dynamic,
|
||||||
EHFrame,
|
EHFrame,
|
||||||
EHFrameHdr,
|
EHFrameHdr,
|
||||||
|
@ -738,60 +737,12 @@ private:
|
||||||
std::vector<FdeData> Fdes;
|
std::vector<FdeData> Fdes;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class ELFT> class BuildIdSection : public OutputSectionBase<ELFT> {
|
|
||||||
typedef OutputSectionBase<ELFT> Base;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void writeTo(uint8_t *Buf) override;
|
|
||||||
virtual void writeBuildId(ArrayRef<uint8_t> Buf) = 0;
|
|
||||||
typename Base::Kind getKind() const override { return Base::BuildId; }
|
|
||||||
static bool classof(const Base *B) { return B->getKind() == Base::BuildId; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
BuildIdSection(size_t HashSize);
|
|
||||||
size_t HashSize;
|
|
||||||
uint8_t *HashBuf = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
class BuildIdFastHash final : public BuildIdSection<ELFT> {
|
|
||||||
public:
|
|
||||||
BuildIdFastHash() : BuildIdSection<ELFT>(8) {}
|
|
||||||
void writeBuildId(ArrayRef<uint8_t> Buf) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ELFT> class BuildIdMd5 final : public BuildIdSection<ELFT> {
|
|
||||||
public:
|
|
||||||
BuildIdMd5() : BuildIdSection<ELFT>(16) {}
|
|
||||||
void writeBuildId(ArrayRef<uint8_t> Buf) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ELFT> class BuildIdSha1 final : public BuildIdSection<ELFT> {
|
|
||||||
public:
|
|
||||||
BuildIdSha1() : BuildIdSection<ELFT>(20) {}
|
|
||||||
void writeBuildId(ArrayRef<uint8_t> Buf) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ELFT> class BuildIdUuid final : public BuildIdSection<ELFT> {
|
|
||||||
public:
|
|
||||||
BuildIdUuid() : BuildIdSection<ELFT>(16) {}
|
|
||||||
void writeBuildId(ArrayRef<uint8_t> Buf) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
class BuildIdHexstring final : public BuildIdSection<ELFT> {
|
|
||||||
public:
|
|
||||||
BuildIdHexstring();
|
|
||||||
void writeBuildId(ArrayRef<uint8_t>) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
// All output sections that are hadnled by the linker specially are
|
// All output sections that are hadnled by the linker specially are
|
||||||
// globally accessible. Writer initializes them, so don't use them
|
// globally accessible. Writer initializes them, so don't use them
|
||||||
// until Writer is initialized.
|
// until Writer is initialized.
|
||||||
template <class ELFT> struct Out {
|
template <class ELFT> struct Out {
|
||||||
typedef typename ELFT::uint uintX_t;
|
typedef typename ELFT::uint uintX_t;
|
||||||
typedef typename ELFT::Phdr Elf_Phdr;
|
typedef typename ELFT::Phdr Elf_Phdr;
|
||||||
static BuildIdSection<ELFT> *BuildId;
|
|
||||||
static DynamicSection<ELFT> *Dynamic;
|
static DynamicSection<ELFT> *Dynamic;
|
||||||
static EhFrameHeader<ELFT> *EhFrameHdr;
|
static EhFrameHeader<ELFT> *EhFrameHdr;
|
||||||
static EhOutputSection<ELFT> *EhFrame;
|
static EhOutputSection<ELFT> *EhFrame;
|
||||||
|
@ -862,7 +813,6 @@ template <class ELFT> uint64_t getHeaderSize() {
|
||||||
return Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
|
return Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> BuildIdSection<ELFT> *Out<ELFT>::BuildId;
|
|
||||||
template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic;
|
template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic;
|
||||||
template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;
|
template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;
|
||||||
template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;
|
template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;
|
||||||
|
|
|
@ -50,6 +50,7 @@ private:
|
||||||
|
|
||||||
void copyLocalSymbols();
|
void copyLocalSymbols();
|
||||||
void addReservedSymbols();
|
void addReservedSymbols();
|
||||||
|
void addInputSec(InputSectionBase<ELFT> *S);
|
||||||
void createSections();
|
void createSections();
|
||||||
void forEachRelSec(std::function<void(InputSectionBase<ELFT> &,
|
void forEachRelSec(std::function<void(InputSectionBase<ELFT> &,
|
||||||
const typename ELFT::Shdr &)> Fn);
|
const typename ELFT::Shdr &)> Fn);
|
||||||
|
@ -209,7 +210,6 @@ template <class ELFT> void elf::writeResult() {
|
||||||
VerDef.reset(new VersionDefinitionSection<ELFT>());
|
VerDef.reset(new VersionDefinitionSection<ELFT>());
|
||||||
|
|
||||||
Out<ELFT>::Bss = &Bss;
|
Out<ELFT>::Bss = &Bss;
|
||||||
Out<ELFT>::BuildId = BuildId.get();
|
|
||||||
Out<ELFT>::DynStrTab = DynStrTab.get();
|
Out<ELFT>::DynStrTab = DynStrTab.get();
|
||||||
Out<ELFT>::DynSymTab = DynSymTab.get();
|
Out<ELFT>::DynSymTab = DynSymTab.get();
|
||||||
Out<ELFT>::Dynamic = &Dynamic;
|
Out<ELFT>::Dynamic = &Dynamic;
|
||||||
|
@ -241,6 +241,10 @@ template <class ELFT> void elf::writeResult() {
|
||||||
Out<ELFT>::InitArray = nullptr;
|
Out<ELFT>::InitArray = nullptr;
|
||||||
Out<ELFT>::FiniArray = nullptr;
|
Out<ELFT>::FiniArray = nullptr;
|
||||||
|
|
||||||
|
// Initialize linker generated sections
|
||||||
|
In<ELFT>::BuildId = BuildId.get();
|
||||||
|
In<ELFT>::Sections = {BuildId.get()};
|
||||||
|
|
||||||
Writer<ELFT>().run();
|
Writer<ELFT>().run();
|
||||||
Out<ELFT>::Pool.clear();
|
Out<ELFT>::Pool.clear();
|
||||||
}
|
}
|
||||||
|
@ -696,28 +700,29 @@ void Writer<ELFT>::forEachRelSec(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void Writer<ELFT>::createSections() {
|
template <class ELFT>
|
||||||
auto Add = [&](InputSectionBase<ELFT> *IS) {
|
void Writer<ELFT>::addInputSec(InputSectionBase<ELFT> *IS) {
|
||||||
if (isDiscarded(IS)) {
|
if (isDiscarded(IS)) {
|
||||||
reportDiscarded(IS);
|
reportDiscarded(IS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
OutputSectionBase<ELFT> *Sec;
|
OutputSectionBase<ELFT> *Sec;
|
||||||
bool IsNew;
|
bool IsNew;
|
||||||
StringRef OutsecName = getOutputSectionName(IS->Name);
|
StringRef OutsecName = getOutputSectionName(IS->Name);
|
||||||
std::tie(Sec, IsNew) = Factory.create(IS, OutsecName);
|
std::tie(Sec, IsNew) = Factory.create(IS, OutsecName);
|
||||||
if (IsNew)
|
if (IsNew)
|
||||||
OutputSections.push_back(Sec);
|
OutputSections.push_back(Sec);
|
||||||
Sec->addSection(IS);
|
Sec->addSection(IS);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
template <class ELFT> void Writer<ELFT>::createSections() {
|
||||||
for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
|
for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
|
||||||
for (InputSectionBase<ELFT> *IS : F->getSections())
|
for (InputSectionBase<ELFT> *IS : F->getSections())
|
||||||
Add(IS);
|
addInputSec(IS);
|
||||||
|
|
||||||
for (BinaryFile *F : Symtab<ELFT>::X->getBinaryFiles())
|
for (BinaryFile *F : Symtab<ELFT>::X->getBinaryFiles())
|
||||||
for (InputSectionData *ID : F->getSections())
|
for (InputSectionData *ID : F->getSections())
|
||||||
Add(cast<InputSection<ELFT>>(ID));
|
addInputSec(cast<InputSection<ELFT>>(ID));
|
||||||
|
|
||||||
sortInitFini(findSection(".init_array"));
|
sortInitFini(findSection(".init_array"));
|
||||||
sortInitFini(findSection(".fini_array"));
|
sortInitFini(findSection(".fini_array"));
|
||||||
|
@ -847,6 +852,11 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||||
// This function adds linker-created Out<ELFT>::* sections.
|
// This function adds linker-created Out<ELFT>::* sections.
|
||||||
addPredefinedSections();
|
addPredefinedSections();
|
||||||
|
|
||||||
|
// Adds linker generated input sections to
|
||||||
|
// corresponding output sections.
|
||||||
|
for (InputSection<ELFT> *S : In<ELFT>::Sections)
|
||||||
|
addInputSec(S);
|
||||||
|
|
||||||
sortSections();
|
sortSections();
|
||||||
|
|
||||||
unsigned I = 1;
|
unsigned I = 1;
|
||||||
|
@ -855,6 +865,11 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||||
Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
|
Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finalize linker generated sections.
|
||||||
|
for (InputSection<ELFT> *S : In<ELFT>::Sections)
|
||||||
|
if (S && S->OutSec)
|
||||||
|
S->OutSec->assignOffsets();
|
||||||
|
|
||||||
// Finalizers fix each section's size.
|
// Finalizers fix each section's size.
|
||||||
// .dynsym is finalized early since that may fill up .gnu.hash.
|
// .dynsym is finalized early since that may fill up .gnu.hash.
|
||||||
if (Out<ELFT>::DynSymTab)
|
if (Out<ELFT>::DynSymTab)
|
||||||
|
@ -899,12 +914,6 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
|
||||||
OutputSections.push_back(OS);
|
OutputSections.push_back(OS);
|
||||||
};
|
};
|
||||||
|
|
||||||
// A core file does not usually contain unmodified segments except
|
|
||||||
// the first page of the executable. Add the build ID section to beginning of
|
|
||||||
// the file so that the section is included in the first page.
|
|
||||||
if (Out<ELFT>::BuildId)
|
|
||||||
OutputSections.insert(OutputSections.begin(), Out<ELFT>::BuildId);
|
|
||||||
|
|
||||||
// Add .interp at first because some loaders want to see that section
|
// Add .interp at first because some loaders want to see that section
|
||||||
// on the first page of the executable file when loaded into memory.
|
// on the first page of the executable file when loaded into memory.
|
||||||
if (Out<ELFT>::Interp)
|
if (Out<ELFT>::Interp)
|
||||||
|
@ -1484,13 +1493,13 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void Writer<ELFT>::writeBuildId() {
|
template <class ELFT> void Writer<ELFT>::writeBuildId() {
|
||||||
if (!Out<ELFT>::BuildId)
|
if (!In<ELFT>::BuildId || !In<ELFT>::BuildId->OutSec)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Compute a hash of all sections of the output file.
|
// Compute a hash of all sections of the output file.
|
||||||
uint8_t *Start = Buffer->getBufferStart();
|
uint8_t *Start = Buffer->getBufferStart();
|
||||||
uint8_t *End = Start + FileSize;
|
uint8_t *End = Start + FileSize;
|
||||||
Out<ELFT>::BuildId->writeBuildId({Start, End});
|
In<ELFT>::BuildId->writeBuildId({Start, End});
|
||||||
}
|
}
|
||||||
|
|
||||||
template void elf::writeResult<ELF32LE>();
|
template void elf::writeResult<ELF32LE>();
|
||||||
|
|
|
@ -23,9 +23,9 @@ _start:
|
||||||
.section .note.test, "a", @note
|
.section .note.test, "a", @note
|
||||||
.quad 42
|
.quad 42
|
||||||
|
|
||||||
|
# DEFAULT: Contents of section .note.test:
|
||||||
# DEFAULT: Contents of section .note.gnu.build-id:
|
# DEFAULT: Contents of section .note.gnu.build-id:
|
||||||
# DEFAULT-NEXT: 04000000 08000000 03000000 474e5500 ............GNU.
|
# DEFAULT-NEXT: 04000000 08000000 03000000 474e5500 ............GNU.
|
||||||
# DEFAULT: Contents of section .note.test:
|
|
||||||
|
|
||||||
# MD5: Contents of section .note.gnu.build-id:
|
# MD5: Contents of section .note.gnu.build-id:
|
||||||
# MD5-NEXT: 04000000 10000000 03000000 474e5500 ............GNU.
|
# MD5-NEXT: 04000000 10000000 03000000 474e5500 ............GNU.
|
||||||
|
|
Loading…
Reference in New Issue