mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-04 08:16:49 +00:00
[ELF] Wrap things in namespace lld { namespace elf {
, NFC
This makes it clear `ELF/**/*.cpp` files define things in the `lld::elf` namespace and simplifies `elf::foo` to `foo`. Reviewed By: atanasyan, grimar, ruiu Differential Revision: https://reviews.llvm.org/D68323 llvm-svn: 373885
This commit is contained in:
parent
5761e3cef4
commit
bd8cfe65f5
@ -17,13 +17,14 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
// Page(Expr) is the page address of the expression Expr, defined
|
// Page(Expr) is the page address of the expression Expr, defined
|
||||||
// as (Expr & ~0xFFF). (This applies even if the machine page size
|
// as (Expr & ~0xFFF). (This applies even if the machine page size
|
||||||
// supported by the platform has a different value.)
|
// supported by the platform has a different value.)
|
||||||
uint64_t elf::getAArch64Page(uint64_t expr) {
|
uint64_t getAArch64Page(uint64_t expr) {
|
||||||
return expr & ~static_cast<uint64_t>(0xFFF);
|
return expr & ~static_cast<uint64_t>(0xFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,4 +680,7 @@ static TargetInfo *getTargetInfo() {
|
|||||||
return &t;
|
return &t;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getAArch64TargetInfo() { return getTargetInfo(); }
|
TargetInfo *getAArch64TargetInfo() { return getTargetInfo(); }
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -17,8 +17,9 @@ using namespace llvm;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class AMDGPU final : public TargetInfo {
|
class AMDGPU final : public TargetInfo {
|
||||||
@ -107,7 +108,10 @@ RelType AMDGPU::getDynRel(RelType type) const {
|
|||||||
return R_AMDGPU_NONE;
|
return R_AMDGPU_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getAMDGPUTargetInfo() {
|
TargetInfo *getAMDGPUTargetInfo() {
|
||||||
static AMDGPU target;
|
static AMDGPU target;
|
||||||
return ⌖
|
return ⌖
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -18,8 +18,9 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class ARM final : public TargetInfo {
|
class ARM final : public TargetInfo {
|
||||||
@ -600,7 +601,10 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getARMTargetInfo() {
|
TargetInfo *getARMTargetInfo() {
|
||||||
static ARM target;
|
static ARM target;
|
||||||
return ⌖
|
return ⌖
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -36,8 +36,9 @@ using namespace llvm;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class AVR final : public TargetInfo {
|
class AVR final : public TargetInfo {
|
||||||
@ -70,7 +71,10 @@ void AVR::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getAVRTargetInfo() {
|
TargetInfo *getAVRTargetInfo() {
|
||||||
static AVR target;
|
static AVR target;
|
||||||
return ⌖
|
return ⌖
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -19,8 +19,9 @@ using namespace llvm;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class Hexagon final : public TargetInfo {
|
class Hexagon final : public TargetInfo {
|
||||||
@ -318,7 +319,10 @@ RelType Hexagon::getDynRel(RelType type) const {
|
|||||||
return R_HEX_NONE;
|
return R_HEX_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getHexagonTargetInfo() {
|
TargetInfo *getHexagonTargetInfo() {
|
||||||
static Hexagon target;
|
static Hexagon target;
|
||||||
return ⌖
|
return ⌖
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -26,8 +26,9 @@ using namespace llvm;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class MSP430 final : public TargetInfo {
|
class MSP430 final : public TargetInfo {
|
||||||
@ -87,7 +88,10 @@ void MSP430::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getMSP430TargetInfo() {
|
TargetInfo *getMSP430TargetInfo() {
|
||||||
static MSP430 target;
|
static MSP430 target;
|
||||||
return ⌖
|
return ⌖
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
|
||||||
|
|
||||||
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
namespace {
|
namespace {
|
||||||
template <class ELFT> class MIPS final : public TargetInfo {
|
template <class ELFT> class MIPS final : public TargetInfo {
|
||||||
public:
|
public:
|
||||||
@ -721,7 +721,7 @@ template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType type) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return true if the symbol is a PIC function.
|
// Return true if the symbol is a PIC function.
|
||||||
template <class ELFT> bool elf::isMipsPIC(const Defined *sym) {
|
template <class ELFT> bool isMipsPIC(const Defined *sym) {
|
||||||
if (!sym->isFunc())
|
if (!sym->isFunc())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -739,17 +739,20 @@ template <class ELFT> bool elf::isMipsPIC(const Defined *sym) {
|
|||||||
return file->getObj().getHeader()->e_flags & EF_MIPS_PIC;
|
return file->getObj().getHeader()->e_flags & EF_MIPS_PIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
|
template <class ELFT> TargetInfo *getMipsTargetInfo() {
|
||||||
static MIPS<ELFT> target;
|
static MIPS<ELFT> target;
|
||||||
return ⌖
|
return ⌖
|
||||||
}
|
}
|
||||||
|
|
||||||
template TargetInfo *elf::getMipsTargetInfo<ELF32LE>();
|
template TargetInfo *getMipsTargetInfo<ELF32LE>();
|
||||||
template TargetInfo *elf::getMipsTargetInfo<ELF32BE>();
|
template TargetInfo *getMipsTargetInfo<ELF32BE>();
|
||||||
template TargetInfo *elf::getMipsTargetInfo<ELF64LE>();
|
template TargetInfo *getMipsTargetInfo<ELF64LE>();
|
||||||
template TargetInfo *elf::getMipsTargetInfo<ELF64BE>();
|
template TargetInfo *getMipsTargetInfo<ELF64BE>();
|
||||||
|
|
||||||
template bool elf::isMipsPIC<ELF32LE>(const Defined *);
|
template bool isMipsPIC<ELF32LE>(const Defined *);
|
||||||
template bool elf::isMipsPIC<ELF32BE>(const Defined *);
|
template bool isMipsPIC<ELF32BE>(const Defined *);
|
||||||
template bool elf::isMipsPIC<ELF64LE>(const Defined *);
|
template bool isMipsPIC<ELF64LE>(const Defined *);
|
||||||
template bool elf::isMipsPIC<ELF64BE>(const Defined *);
|
template bool isMipsPIC<ELF64BE>(const Defined *);
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -23,8 +23,8 @@ using namespace llvm;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct ArchTreeEdge {
|
struct ArchTreeEdge {
|
||||||
@ -294,7 +294,7 @@ static uint32_t getArchFlags(ArrayRef<FileFlags> files) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> uint32_t elf::calcMipsEFlags() {
|
template <class ELFT> uint32_t calcMipsEFlags() {
|
||||||
std::vector<FileFlags> v;
|
std::vector<FileFlags> v;
|
||||||
for (InputFile *f : objectFiles)
|
for (InputFile *f : objectFiles)
|
||||||
v.push_back({f, cast<ObjFile<ELFT>>(f)->getObj().getHeader()->e_flags});
|
v.push_back({f, cast<ObjFile<ELFT>>(f)->getObj().getHeader()->e_flags});
|
||||||
@ -350,8 +350,7 @@ static StringRef getMipsFpAbiName(uint8_t fpAbi) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t elf::getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag,
|
uint8_t getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag, StringRef fileName) {
|
||||||
StringRef fileName) {
|
|
||||||
if (compareMipsFpAbi(newFlag, oldFlag) >= 0)
|
if (compareMipsFpAbi(newFlag, oldFlag) >= 0)
|
||||||
return newFlag;
|
return newFlag;
|
||||||
if (compareMipsFpAbi(oldFlag, newFlag) < 0)
|
if (compareMipsFpAbi(oldFlag, newFlag) < 0)
|
||||||
@ -367,7 +366,7 @@ template <class ELFT> static bool isN32Abi(const InputFile *f) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool elf::isMipsN32Abi(const InputFile *f) {
|
bool isMipsN32Abi(const InputFile *f) {
|
||||||
switch (config->ekind) {
|
switch (config->ekind) {
|
||||||
case ELF32LEKind:
|
case ELF32LEKind:
|
||||||
return isN32Abi<ELF32LE>(f);
|
return isN32Abi<ELF32LE>(f);
|
||||||
@ -382,14 +381,17 @@ bool elf::isMipsN32Abi(const InputFile *f) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool elf::isMicroMips() { return config->eflags & EF_MIPS_MICROMIPS; }
|
bool isMicroMips() { return config->eflags & EF_MIPS_MICROMIPS; }
|
||||||
|
|
||||||
bool elf::isMipsR6() {
|
bool isMipsR6() {
|
||||||
uint32_t arch = config->eflags & EF_MIPS_ARCH;
|
uint32_t arch = config->eflags & EF_MIPS_ARCH;
|
||||||
return arch == EF_MIPS_ARCH_32R6 || arch == EF_MIPS_ARCH_64R6;
|
return arch == EF_MIPS_ARCH_32R6 || arch == EF_MIPS_ARCH_64R6;
|
||||||
}
|
}
|
||||||
|
|
||||||
template uint32_t elf::calcMipsEFlags<ELF32LE>();
|
template uint32_t calcMipsEFlags<ELF32LE>();
|
||||||
template uint32_t elf::calcMipsEFlags<ELF32BE>();
|
template uint32_t calcMipsEFlags<ELF32BE>();
|
||||||
template uint32_t elf::calcMipsEFlags<ELF64LE>();
|
template uint32_t calcMipsEFlags<ELF64LE>();
|
||||||
template uint32_t elf::calcMipsEFlags<ELF64BE>();
|
template uint32_t calcMipsEFlags<ELF64BE>();
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -16,8 +16,9 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class PPC final : public TargetInfo {
|
class PPC final : public TargetInfo {
|
||||||
@ -61,7 +62,7 @@ static void writeFromHalf16(uint8_t *loc, uint32_t insn) {
|
|||||||
write32(config->isLE ? loc : loc - 2, insn);
|
write32(config->isLE ? loc : loc - 2, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf::writePPC32GlinkSection(uint8_t *buf, size_t numEntries) {
|
void writePPC32GlinkSection(uint8_t *buf, size_t numEntries) {
|
||||||
// On PPC Secure PLT ABI, bl foo@plt jumps to a call stub, which loads an
|
// On PPC Secure PLT ABI, bl foo@plt jumps to a call stub, which loads an
|
||||||
// absolute address from a specific .plt slot (usually called .got.plt on
|
// absolute address from a specific .plt slot (usually called .got.plt on
|
||||||
// other targets) and jumps there.
|
// other targets) and jumps there.
|
||||||
@ -435,7 +436,10 @@ void PPC::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getPPCTargetInfo() {
|
TargetInfo *getPPCTargetInfo() {
|
||||||
static PPC target;
|
static PPC target;
|
||||||
return ⌖
|
return ⌖
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -16,8 +16,9 @@ using namespace llvm;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
static uint64_t ppc64TocOffset = 0x8000;
|
static uint64_t ppc64TocOffset = 0x8000;
|
||||||
static uint64_t dynamicThreadPointerOffset = 0x8000;
|
static uint64_t dynamicThreadPointerOffset = 0x8000;
|
||||||
@ -59,7 +60,7 @@ enum DFormOpcd {
|
|||||||
ADDI = 14
|
ADDI = 14
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64_t elf::getPPC64TocBase() {
|
uint64_t getPPC64TocBase() {
|
||||||
// The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The
|
// The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The
|
||||||
// TOC starts where the first of these sections starts. We always create a
|
// TOC starts where the first of these sections starts. We always create a
|
||||||
// .got when we see a relocation that uses it, so for us the start is always
|
// .got when we see a relocation that uses it, so for us the start is always
|
||||||
@ -73,7 +74,7 @@ uint64_t elf::getPPC64TocBase() {
|
|||||||
return tocVA + ppc64TocOffset;
|
return tocVA + ppc64TocOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther) {
|
unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther) {
|
||||||
// The offset is encoded into the 3 most significant bits of the st_other
|
// The offset is encoded into the 3 most significant bits of the st_other
|
||||||
// field, with some special values described in section 3.4.1 of the ABI:
|
// field, with some special values described in section 3.4.1 of the ABI:
|
||||||
// 0 --> Zero offset between the GEP and LEP, and the function does NOT use
|
// 0 --> Zero offset between the GEP and LEP, and the function does NOT use
|
||||||
@ -98,7 +99,7 @@ unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool elf::isPPC64SmallCodeModelTocReloc(RelType type) {
|
bool isPPC64SmallCodeModelTocReloc(RelType type) {
|
||||||
// The only small code model relocations that access the .toc section.
|
// The only small code model relocations that access the .toc section.
|
||||||
return type == R_PPC64_TOC16 || type == R_PPC64_TOC16_DS;
|
return type == R_PPC64_TOC16 || type == R_PPC64_TOC16_DS;
|
||||||
}
|
}
|
||||||
@ -153,8 +154,8 @@ getRelaTocSymAndAddend(InputSectionBase *tocSec, uint64_t offset) {
|
|||||||
// ld/lwa 3, 0(3) # load the value from the address
|
// ld/lwa 3, 0(3) # load the value from the address
|
||||||
//
|
//
|
||||||
// Returns true if the relaxation is performed.
|
// Returns true if the relaxation is performed.
|
||||||
bool elf::tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel,
|
bool tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel,
|
||||||
uint8_t *bufLoc) {
|
uint8_t *bufLoc) {
|
||||||
assert(config->tocOptimize);
|
assert(config->tocOptimize);
|
||||||
if (rel.addend < 0)
|
if (rel.addend < 0)
|
||||||
return false;
|
return false;
|
||||||
@ -458,7 +459,7 @@ void PPC64::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned elf::getPPCDFormOp(unsigned secondaryOp) {
|
unsigned getPPCDFormOp(unsigned secondaryOp) {
|
||||||
switch (secondaryOp) {
|
switch (secondaryOp) {
|
||||||
case LBZX:
|
case LBZX:
|
||||||
return LBZ;
|
return LBZ;
|
||||||
@ -1093,7 +1094,10 @@ bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getPPC64TargetInfo() {
|
TargetInfo *getPPC64TargetInfo() {
|
||||||
static PPC64 target;
|
static PPC64 target;
|
||||||
return ⌖
|
return ⌖
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -14,8 +14,9 @@ using namespace llvm;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -436,7 +437,10 @@ void RISCV::relocateOne(uint8_t *loc, const RelType type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getRISCVTargetInfo() {
|
TargetInfo *getRISCVTargetInfo() {
|
||||||
static RISCV target;
|
static RISCV target;
|
||||||
return ⌖
|
return ⌖
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -16,8 +16,9 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class SPARCV9 final : public TargetInfo {
|
class SPARCV9 final : public TargetInfo {
|
||||||
@ -143,7 +144,10 @@ void SPARCV9::writePlt(uint8_t *buf, uint64_t gotEntryAddr,
|
|||||||
relocateOne(buf + 4, R_SPARC_WDISP19, -(off + 4 - pltEntrySize));
|
relocateOne(buf + 4, R_SPARC_WDISP19, -(off + 4 - pltEntrySize));
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getSPARCV9TargetInfo() {
|
TargetInfo *getSPARCV9TargetInfo() {
|
||||||
static SPARCV9 target;
|
static SPARCV9 target;
|
||||||
return ⌖
|
return ⌖
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -16,8 +16,9 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class X86 : public TargetInfo {
|
class X86 : public TargetInfo {
|
||||||
@ -539,7 +540,7 @@ void RetpolineNoPic::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
|
|||||||
write32le(buf + 22, -off - 26);
|
write32le(buf + 22, -off - 26);
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getX86TargetInfo() {
|
TargetInfo *getX86TargetInfo() {
|
||||||
if (config->zRetpolineplt) {
|
if (config->zRetpolineplt) {
|
||||||
if (config->isPic) {
|
if (config->isPic) {
|
||||||
static RetpolinePic t;
|
static RetpolinePic t;
|
||||||
@ -552,3 +553,6 @@ TargetInfo *elf::getX86TargetInfo() {
|
|||||||
static X86 t;
|
static X86 t;
|
||||||
return &t;
|
return &t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -18,8 +18,9 @@ using namespace llvm;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class X86_64 : public TargetInfo {
|
class X86_64 : public TargetInfo {
|
||||||
@ -698,4 +699,7 @@ static TargetInfo *getTargetInfo() {
|
|||||||
return &t;
|
return &t;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getX86_64TargetInfo() { return getTargetInfo(); }
|
TargetInfo *getX86_64TargetInfo() { return getTargetInfo(); }
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -48,8 +48,9 @@
|
|||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct Edge {
|
struct Edge {
|
||||||
@ -264,6 +265,9 @@ DenseMap<const InputSectionBase *, int> CallGraphSort::run() {
|
|||||||
// This first builds a call graph based on the profile data then merges sections
|
// This first builds a call graph based on the profile data then merges sections
|
||||||
// according to the C³ huristic. All clusters are then sorted by a density
|
// according to the C³ huristic. All clusters are then sorted by a density
|
||||||
// metric to further improve locality.
|
// metric to further improve locality.
|
||||||
DenseMap<const InputSectionBase *, int> elf::computeCallGraphProfileOrder() {
|
DenseMap<const InputSectionBase *, int> computeCallGraphProfileOrder() {
|
||||||
return CallGraphSort().run();
|
return CallGraphSort().run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -22,9 +22,9 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
|
||||||
|
|
||||||
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) {
|
template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) {
|
||||||
for (InputSectionBase *sec : obj->getSections()) {
|
for (InputSectionBase *sec : obj->getSections()) {
|
||||||
if (!sec)
|
if (!sec)
|
||||||
@ -124,7 +124,10 @@ Optional<RelocAddrEntry> LLDDwarfObj<ELFT>::find(const llvm::DWARFSection &s,
|
|||||||
return findAux(*sec.sec, pos, sec.sec->template rels<ELFT>());
|
return findAux(*sec.sec, pos, sec.sec->template rels<ELFT>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template class elf::LLDDwarfObj<ELF32LE>;
|
template class LLDDwarfObj<ELF32LE>;
|
||||||
template class elf::LLDDwarfObj<ELF32BE>;
|
template class LLDDwarfObj<ELF32BE>;
|
||||||
template class elf::LLDDwarfObj<ELF64LE>;
|
template class LLDDwarfObj<ELF64LE>;
|
||||||
template class elf::LLDDwarfObj<ELF64BE>;
|
template class LLDDwarfObj<ELF64BE>;
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -66,17 +66,16 @@ using namespace llvm::object;
|
|||||||
using namespace llvm::sys;
|
using namespace llvm::sys;
|
||||||
using namespace llvm::support;
|
using namespace llvm::support;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
namespace elf {
|
||||||
|
|
||||||
Configuration *elf::config;
|
Configuration *config;
|
||||||
LinkerDriver *elf::driver;
|
LinkerDriver *driver;
|
||||||
|
|
||||||
static void setConfigs(opt::InputArgList &args);
|
static void setConfigs(opt::InputArgList &args);
|
||||||
static void readConfigs(opt::InputArgList &args);
|
static void readConfigs(opt::InputArgList &args);
|
||||||
|
|
||||||
bool elf::link(ArrayRef<const char *> args, bool canExitEarly,
|
bool link(ArrayRef<const char *> args, bool canExitEarly, raw_ostream &error) {
|
||||||
raw_ostream &error) {
|
|
||||||
errorHandler().logName = args::getFilenameWithoutExe(args[0]);
|
errorHandler().logName = args::getFilenameWithoutExe(args[0]);
|
||||||
errorHandler().errorLimitExceededMsg =
|
errorHandler().errorLimitExceededMsg =
|
||||||
"too many errors emitted, stopping now (use "
|
"too many errors emitted, stopping now (use "
|
||||||
@ -1970,3 +1969,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
|
|||||||
// Write the result to the file.
|
// Write the result to the file.
|
||||||
writeResult<ELFT>();
|
writeResult<ELFT>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -30,8 +30,8 @@ using namespace llvm;
|
|||||||
using namespace llvm::sys;
|
using namespace llvm::sys;
|
||||||
using namespace llvm::opt;
|
using namespace llvm::opt;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
namespace elf {
|
||||||
|
|
||||||
// Create OptTable
|
// Create OptTable
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> argv) {
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf::printHelp() {
|
void printHelp() {
|
||||||
ELFOptTable().PrintHelp(
|
ELFOptTable().PrintHelp(
|
||||||
outs(), (config->progName + " [options] file...").str().c_str(), "lld",
|
outs(), (config->progName + " [options] file...").str().c_str(), "lld",
|
||||||
false /*ShowHidden*/, true /*ShowAllAliases*/);
|
false /*ShowHidden*/, true /*ShowAllAliases*/);
|
||||||
@ -165,7 +165,7 @@ static std::string rewritePath(StringRef s) {
|
|||||||
|
|
||||||
// Reconstructs command line arguments so that so that you can re-run
|
// Reconstructs command line arguments so that so that you can re-run
|
||||||
// the same command with the same inputs. This is for --reproduce.
|
// the same command with the same inputs. This is for --reproduce.
|
||||||
std::string elf::createResponseFile(const opt::InputArgList &args) {
|
std::string createResponseFile(const opt::InputArgList &args) {
|
||||||
SmallString<0> data;
|
SmallString<0> data;
|
||||||
raw_svector_ostream os(data);
|
raw_svector_ostream os(data);
|
||||||
os << "--chroot .\n";
|
os << "--chroot .\n";
|
||||||
@ -216,7 +216,7 @@ static Optional<std::string> findFile(StringRef path1, const Twine &path2) {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<std::string> elf::findFromSearchPaths(StringRef path) {
|
Optional<std::string> findFromSearchPaths(StringRef path) {
|
||||||
for (StringRef dir : config->searchPaths)
|
for (StringRef dir : config->searchPaths)
|
||||||
if (Optional<std::string> s = findFile(dir, path))
|
if (Optional<std::string> s = findFile(dir, path))
|
||||||
return s;
|
return s;
|
||||||
@ -225,7 +225,7 @@ Optional<std::string> elf::findFromSearchPaths(StringRef path) {
|
|||||||
|
|
||||||
// This is for -l<basename>. We'll look for lib<basename>.so or lib<basename>.a from
|
// This is for -l<basename>. We'll look for lib<basename>.so or lib<basename>.a from
|
||||||
// search paths.
|
// search paths.
|
||||||
Optional<std::string> elf::searchLibraryBaseName(StringRef name) {
|
Optional<std::string> searchLibraryBaseName(StringRef name) {
|
||||||
for (StringRef dir : config->searchPaths) {
|
for (StringRef dir : config->searchPaths) {
|
||||||
if (!config->isStatic)
|
if (!config->isStatic)
|
||||||
if (Optional<std::string> s = findFile(dir, "lib" + name + ".so"))
|
if (Optional<std::string> s = findFile(dir, "lib" + name + ".so"))
|
||||||
@ -237,17 +237,20 @@ Optional<std::string> elf::searchLibraryBaseName(StringRef name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is for -l<namespec>.
|
// This is for -l<namespec>.
|
||||||
Optional<std::string> elf::searchLibrary(StringRef name) {
|
Optional<std::string> searchLibrary(StringRef name) {
|
||||||
if (name.startswith(":"))
|
if (name.startswith(":"))
|
||||||
return findFromSearchPaths(name.substr(1));
|
return findFromSearchPaths(name.substr(1));
|
||||||
return searchLibraryBaseName (name);
|
return searchLibraryBaseName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a linker/version script doesn't exist in the current directory, we also
|
// If a linker/version script doesn't exist in the current directory, we also
|
||||||
// look for the script in the '-L' search paths. This matches the behaviour of
|
// look for the script in the '-L' search paths. This matches the behaviour of
|
||||||
// '-T', --version-script=, and linker script INPUT() command in ld.bfd.
|
// '-T', --version-script=, and linker script INPUT() command in ld.bfd.
|
||||||
Optional<std::string> elf::searchScript(StringRef name) {
|
Optional<std::string> searchScript(StringRef name) {
|
||||||
if (fs::exists(name))
|
if (fs::exists(name))
|
||||||
return name.str();
|
return name.str();
|
||||||
return findFromSearchPaths(name);
|
return findFromSearchPaths(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -30,9 +30,8 @@ using namespace llvm::ELF;
|
|||||||
using namespace llvm::dwarf;
|
using namespace llvm::dwarf;
|
||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class EhReader {
|
class EhReader {
|
||||||
public:
|
public:
|
||||||
@ -57,7 +56,7 @@ private:
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t elf::readEhRecordSize(InputSectionBase *s, size_t off) {
|
size_t readEhRecordSize(InputSectionBase *s, size_t off) {
|
||||||
return EhReader(s, s->data().slice(off)).readEhRecordSize();
|
return EhReader(s, s->data().slice(off)).readEhRecordSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +148,7 @@ void EhReader::skipAugP() {
|
|||||||
d = d.slice(size);
|
d = d.slice(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t elf::getFdeEncoding(EhSectionPiece *p) {
|
uint8_t getFdeEncoding(EhSectionPiece *p) {
|
||||||
return EhReader(p->sec, p->data()).getFdeEncoding();
|
return EhReader(p->sec, p->data()).getFdeEncoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,3 +194,6 @@ uint8_t EhReader::getFdeEncoding() {
|
|||||||
}
|
}
|
||||||
return DW_EH_PE_absptr;
|
return DW_EH_PE_absptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -88,12 +88,12 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
|
|
||||||
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
namespace {
|
namespace {
|
||||||
template <class ELFT> class ICF {
|
template <class ELFT> class ICF {
|
||||||
public:
|
public:
|
||||||
@ -512,9 +512,12 @@ template <class ELFT> void ICF<ELFT>::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ICF entry point function.
|
// ICF entry point function.
|
||||||
template <class ELFT> void elf::doIcf() { ICF<ELFT>().run(); }
|
template <class ELFT> void doIcf() { ICF<ELFT>().run(); }
|
||||||
|
|
||||||
template void elf::doIcf<ELF32LE>();
|
template void doIcf<ELF32LE>();
|
||||||
template void elf::doIcf<ELF32BE>();
|
template void doIcf<ELF32BE>();
|
||||||
template void elf::doIcf<ELF64LE>();
|
template void doIcf<ELF64LE>();
|
||||||
template void elf::doIcf<ELF64BE>();
|
template void doIcf<ELF64BE>();
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -37,18 +37,31 @@ using namespace llvm::sys;
|
|||||||
using namespace llvm::sys::fs;
|
using namespace llvm::sys::fs;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
|
||||||
|
std::string toString(const elf::InputFile *f) {
|
||||||
|
if (!f)
|
||||||
|
return "<internal>";
|
||||||
|
|
||||||
|
if (f->toStringCache.empty()) {
|
||||||
|
if (f->archiveName.empty())
|
||||||
|
f->toStringCache = f->getName();
|
||||||
|
else
|
||||||
|
f->toStringCache = (f->archiveName + "(" + f->getName() + ")").str();
|
||||||
|
}
|
||||||
|
return f->toStringCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace elf {
|
||||||
bool InputFile::isInGroup;
|
bool InputFile::isInGroup;
|
||||||
uint32_t InputFile::nextGroupId;
|
uint32_t InputFile::nextGroupId;
|
||||||
std::vector<BinaryFile *> elf::binaryFiles;
|
std::vector<BinaryFile *> binaryFiles;
|
||||||
std::vector<BitcodeFile *> elf::bitcodeFiles;
|
std::vector<BitcodeFile *> bitcodeFiles;
|
||||||
std::vector<LazyObjFile *> elf::lazyObjFiles;
|
std::vector<LazyObjFile *> lazyObjFiles;
|
||||||
std::vector<InputFile *> elf::objectFiles;
|
std::vector<InputFile *> objectFiles;
|
||||||
std::vector<SharedFile *> elf::sharedFiles;
|
std::vector<SharedFile *> sharedFiles;
|
||||||
|
|
||||||
std::unique_ptr<TarWriter> elf::tar;
|
std::unique_ptr<TarWriter> tar;
|
||||||
|
|
||||||
static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) {
|
static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) {
|
||||||
unsigned char size;
|
unsigned char size;
|
||||||
@ -88,7 +101,7 @@ InputFile::InputFile(Kind k, MemoryBufferRef m)
|
|||||||
++nextGroupId;
|
++nextGroupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<MemoryBufferRef> elf::readFile(StringRef path) {
|
Optional<MemoryBufferRef> readFile(StringRef path) {
|
||||||
// The --chroot option changes our virtual root directory.
|
// The --chroot option changes our virtual root directory.
|
||||||
// This is useful when you are dealing with files created by --reproduce.
|
// This is useful when you are dealing with files created by --reproduce.
|
||||||
if (!config->chroot.empty() && path.startswith("/"))
|
if (!config->chroot.empty() && path.startswith("/"))
|
||||||
@ -188,7 +201,7 @@ template <class ELFT> static void doParseFile(InputFile *file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add symbols in File to the symbol table.
|
// Add symbols in File to the symbol table.
|
||||||
void elf::parseFile(InputFile *file) {
|
void parseFile(InputFile *file) {
|
||||||
switch (config->ekind) {
|
switch (config->ekind) {
|
||||||
case ELF32LEKind:
|
case ELF32LEKind:
|
||||||
doParseFile<ELF32LE>(file);
|
doParseFile<ELF32LE>(file);
|
||||||
@ -356,20 +369,6 @@ Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *s,
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
|
|
||||||
std::string lld::toString(const InputFile *f) {
|
|
||||||
if (!f)
|
|
||||||
return "<internal>";
|
|
||||||
|
|
||||||
if (f->toStringCache.empty()) {
|
|
||||||
if (f->archiveName.empty())
|
|
||||||
f->toStringCache = f->getName();
|
|
||||||
else
|
|
||||||
f->toStringCache = (f->archiveName + "(" + f->getName() + ")").str();
|
|
||||||
}
|
|
||||||
return f->toStringCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
ELFFileBase::ELFFileBase(Kind k, MemoryBufferRef mb) : InputFile(k, mb) {
|
ELFFileBase::ELFFileBase(Kind k, MemoryBufferRef mb) : InputFile(k, mb) {
|
||||||
ekind = getELFKind(mb, "");
|
ekind = getELFKind(mb, "");
|
||||||
|
|
||||||
@ -1530,8 +1529,8 @@ void BinaryFile::parse() {
|
|||||||
STV_DEFAULT, STT_OBJECT, data.size(), 0, nullptr});
|
STV_DEFAULT, STT_OBJECT, data.size(), 0, nullptr});
|
||||||
}
|
}
|
||||||
|
|
||||||
InputFile *elf::createObjectFile(MemoryBufferRef mb, StringRef archiveName,
|
InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName,
|
||||||
uint64_t offsetInArchive) {
|
uint64_t offsetInArchive) {
|
||||||
if (isBitcode(mb))
|
if (isBitcode(mb))
|
||||||
return make<BitcodeFile>(mb, archiveName, offsetInArchive);
|
return make<BitcodeFile>(mb, archiveName, offsetInArchive);
|
||||||
|
|
||||||
@ -1622,7 +1621,7 @@ template <class ELFT> void LazyObjFile::parse() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string elf::replaceThinLTOSuffix(StringRef path) {
|
std::string replaceThinLTOSuffix(StringRef path) {
|
||||||
StringRef suffix = config->thinLTOObjectSuffixReplace.first;
|
StringRef suffix = config->thinLTOObjectSuffixReplace.first;
|
||||||
StringRef repl = config->thinLTOObjectSuffixReplace.second;
|
StringRef repl = config->thinLTOObjectSuffixReplace.second;
|
||||||
|
|
||||||
@ -1641,12 +1640,15 @@ template void LazyObjFile::parse<ELF32BE>();
|
|||||||
template void LazyObjFile::parse<ELF64LE>();
|
template void LazyObjFile::parse<ELF64LE>();
|
||||||
template void LazyObjFile::parse<ELF64BE>();
|
template void LazyObjFile::parse<ELF64BE>();
|
||||||
|
|
||||||
template class elf::ObjFile<ELF32LE>;
|
template class ObjFile<ELF32LE>;
|
||||||
template class elf::ObjFile<ELF32BE>;
|
template class ObjFile<ELF32BE>;
|
||||||
template class elf::ObjFile<ELF64LE>;
|
template class ObjFile<ELF64LE>;
|
||||||
template class elf::ObjFile<ELF64BE>;
|
template class ObjFile<ELF64BE>;
|
||||||
|
|
||||||
template void SharedFile::parse<ELF32LE>();
|
template void SharedFile::parse<ELF32LE>();
|
||||||
template void SharedFile::parse<ELF32BE>();
|
template void SharedFile::parse<ELF32BE>();
|
||||||
template void SharedFile::parse<ELF64LE>();
|
template void SharedFile::parse<ELF64LE>();
|
||||||
template void SharedFile::parse<ELF64BE>();
|
template void SharedFile::parse<ELF64BE>();
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -33,15 +33,13 @@ class InputFile;
|
|||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
|
|
||||||
namespace lld {
|
namespace lld {
|
||||||
namespace elf {
|
|
||||||
class InputFile;
|
|
||||||
class InputSectionBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
|
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
|
||||||
std::string toString(const elf::InputFile *f);
|
std::string toString(const elf::InputFile *f);
|
||||||
|
|
||||||
namespace elf {
|
namespace elf {
|
||||||
|
class InputFile;
|
||||||
|
class InputSectionBase;
|
||||||
|
|
||||||
using llvm::object::Archive;
|
using llvm::object::Archive;
|
||||||
|
|
||||||
|
@ -37,16 +37,15 @@ using namespace llvm::support;
|
|||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::sys;
|
using namespace llvm::sys;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
|
||||||
|
|
||||||
std::vector<InputSectionBase *> elf::inputSections;
|
|
||||||
|
|
||||||
// Returns a string to construct an error message.
|
// Returns a string to construct an error message.
|
||||||
std::string lld::toString(const InputSectionBase *sec) {
|
std::string toString(const elf::InputSectionBase *sec) {
|
||||||
return (toString(sec->file) + ":(" + sec->name + ")").str();
|
return (toString(sec->file) + ":(" + sec->name + ")").str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace elf {
|
||||||
|
std::vector<InputSectionBase *> inputSections;
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &file,
|
static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &file,
|
||||||
const typename ELFT::Shdr &hdr) {
|
const typename ELFT::Shdr &hdr) {
|
||||||
@ -619,7 +618,7 @@ static int64_t getTlsTpOffset(const Symbol &s) {
|
|||||||
// Variant 2. Static TLS blocks, followed by alignment padding are placed
|
// Variant 2. Static TLS blocks, followed by alignment padding are placed
|
||||||
// before TP. The alignment padding is added so that (TP - padding -
|
// before TP. The alignment padding is added so that (TP - padding -
|
||||||
// p_memsz) is congruent to p_vaddr modulo p_align.
|
// p_memsz) is congruent to p_vaddr modulo p_align.
|
||||||
elf::PhdrEntry *tls = Out::tlsPhdr;
|
PhdrEntry *tls = Out::tlsPhdr;
|
||||||
switch (config->emachine) {
|
switch (config->emachine) {
|
||||||
// Variant 1.
|
// Variant 1.
|
||||||
case EM_ARM:
|
case EM_ARM:
|
||||||
@ -1082,7 +1081,7 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf,
|
|||||||
end, f->stOther))
|
end, f->stOther))
|
||||||
continue;
|
continue;
|
||||||
if (!getFile<ELFT>()->someNoSplitStack)
|
if (!getFile<ELFT>()->someNoSplitStack)
|
||||||
error(lld::toString(this) + ": " + f->getName() +
|
error(toString(this) + ": " + f->getName() +
|
||||||
" (with -fsplit-stack) calls " + rel.sym->getName() +
|
" (with -fsplit-stack) calls " + rel.sym->getName() +
|
||||||
" (without -fsplit-stack), but couldn't adjust its prologue");
|
" (without -fsplit-stack), but couldn't adjust its prologue");
|
||||||
}
|
}
|
||||||
@ -1345,3 +1344,6 @@ template void EhInputSection::split<ELF32LE>();
|
|||||||
template void EhInputSection::split<ELF32BE>();
|
template void EhInputSection::split<ELF32BE>();
|
||||||
template void EhInputSection::split<ELF64LE>();
|
template void EhInputSection::split<ELF64LE>();
|
||||||
template void EhInputSection::split<ELF64BE>();
|
template void EhInputSection::split<ELF64BE>();
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -42,8 +42,8 @@ using namespace llvm;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
namespace elf {
|
||||||
|
|
||||||
// Creates an empty file to store a list of object files for final
|
// Creates an empty file to store a list of object files for final
|
||||||
// linking of distributed ThinLTO.
|
// linking of distributed ThinLTO.
|
||||||
@ -303,3 +303,6 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
|
|||||||
ret.push_back(createObjectFile(*file));
|
ret.push_back(createObjectFile(*file));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -43,10 +43,10 @@ using namespace llvm;
|
|||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
|
||||||
|
|
||||||
LinkerScript *elf::script;
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
|
LinkerScript *script;
|
||||||
|
|
||||||
static uint64_t getOutputSectionVA(SectionBase *sec) {
|
static uint64_t getOutputSectionVA(SectionBase *sec) {
|
||||||
OutputSection *os = sec->getOutputSection();
|
OutputSection *os = sec->getOutputSection();
|
||||||
@ -1202,3 +1202,6 @@ std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *cmd) {
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -34,9 +34,8 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
namespace elf {
|
||||||
|
|
||||||
using SymbolMapTy = DenseMap<const SectionBase *, SmallVector<Defined *, 4>>;
|
using SymbolMapTy = DenseMap<const SectionBase *, SmallVector<Defined *, 4>>;
|
||||||
|
|
||||||
static constexpr char indent8[] = " "; // 8 spaces
|
static constexpr char indent8[] = " "; // 8 spaces
|
||||||
@ -139,7 +138,7 @@ static void printEhFrame(raw_ostream &os, const EhFrameSection *sec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf::writeMapFile() {
|
void writeMapFile() {
|
||||||
if (config->mapFile.empty())
|
if (config->mapFile.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -228,7 +227,7 @@ static void print(StringRef a, StringRef b) {
|
|||||||
//
|
//
|
||||||
// In this case, strlen is defined by libc.so.6 and used by other two
|
// In this case, strlen is defined by libc.so.6 and used by other two
|
||||||
// files.
|
// files.
|
||||||
void elf::writeCrossReferenceTable() {
|
void writeCrossReferenceTable() {
|
||||||
if (!config->cref)
|
if (!config->cref)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -259,3 +258,6 @@ void elf::writeCrossReferenceTable() {
|
|||||||
print("", toString(file));
|
print("", toString(file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -37,11 +37,11 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::support::endian;
|
|
||||||
|
|
||||||
using namespace lld;
|
namespace endian = llvm::support::endian;
|
||||||
using namespace lld::elf;
|
|
||||||
|
|
||||||
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
namespace {
|
namespace {
|
||||||
template <class ELFT> class MarkLive {
|
template <class ELFT> class MarkLive {
|
||||||
public:
|
public:
|
||||||
@ -141,7 +141,7 @@ void MarkLive<ELFT>::scanEhFrameSection(EhInputSection &eh,
|
|||||||
if (firstRelI == (unsigned)-1)
|
if (firstRelI == (unsigned)-1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (read32<ELFT::TargetEndianness>(piece.data().data() + 4) == 0) {
|
if (endian::read32<ELFT::TargetEndianness>(piece.data().data() + 4) == 0) {
|
||||||
// This is a CIE, we only need to worry about the first relocation. It is
|
// This is a CIE, we only need to worry about the first relocation. It is
|
||||||
// known to point to the personality function.
|
// known to point to the personality function.
|
||||||
resolveReloc(eh, rels[firstRelI], false);
|
resolveReloc(eh, rels[firstRelI], false);
|
||||||
@ -317,7 +317,7 @@ template <class ELFT> void MarkLive<ELFT>::moveToMain() {
|
|||||||
// Before calling this function, Live bits are off for all
|
// Before calling this function, Live bits are off for all
|
||||||
// input sections. This function make some or all of them on
|
// input sections. This function make some or all of them on
|
||||||
// so that they are emitted to the output file.
|
// so that they are emitted to the output file.
|
||||||
template <class ELFT> void elf::markLive() {
|
template <class ELFT> void markLive() {
|
||||||
// If -gc-sections is not given, no sections are removed.
|
// If -gc-sections is not given, no sections are removed.
|
||||||
if (!config->gcSections) {
|
if (!config->gcSections) {
|
||||||
for (InputSectionBase *sec : inputSections)
|
for (InputSectionBase *sec : inputSections)
|
||||||
@ -379,7 +379,10 @@ template <class ELFT> void elf::markLive() {
|
|||||||
message("removing unused section " + toString(sec));
|
message("removing unused section " + toString(sec));
|
||||||
}
|
}
|
||||||
|
|
||||||
template void elf::markLive<ELF32LE>();
|
template void markLive<ELF32LE>();
|
||||||
template void elf::markLive<ELF32BE>();
|
template void markLive<ELF32BE>();
|
||||||
template void elf::markLive<ELF64LE>();
|
template void markLive<ELF64LE>();
|
||||||
template void elf::markLive<ELF64BE>();
|
template void markLive<ELF64BE>();
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -27,9 +27,8 @@ using namespace llvm::object;
|
|||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
namespace elf {
|
||||||
|
|
||||||
uint8_t *Out::bufferStart;
|
uint8_t *Out::bufferStart;
|
||||||
uint8_t Out::first;
|
uint8_t Out::first;
|
||||||
PhdrEntry *Out::tlsPhdr;
|
PhdrEntry *Out::tlsPhdr;
|
||||||
@ -39,7 +38,7 @@ OutputSection *Out::preinitArray;
|
|||||||
OutputSection *Out::initArray;
|
OutputSection *Out::initArray;
|
||||||
OutputSection *Out::finiArray;
|
OutputSection *Out::finiArray;
|
||||||
|
|
||||||
std::vector<OutputSection *> elf::outputSections;
|
std::vector<OutputSection *> outputSections;
|
||||||
|
|
||||||
uint32_t OutputSection::getPhdrFlags() const {
|
uint32_t OutputSection::getPhdrFlags() const {
|
||||||
uint32_t ret = 0;
|
uint32_t ret = 0;
|
||||||
@ -226,7 +225,7 @@ static void sortByOrder(MutableArrayRef<InputSection *> in,
|
|||||||
in[i] = v[i].second;
|
in[i] = v[i].second;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t elf::getHeaderSize() {
|
uint64_t getHeaderSize() {
|
||||||
if (config->oFormatBinary)
|
if (config->oFormatBinary)
|
||||||
return 0;
|
return 0;
|
||||||
return Out::elfHeader->size + Out::programHeaders->size;
|
return Out::elfHeader->size + Out::programHeaders->size;
|
||||||
@ -446,7 +445,7 @@ void OutputSection::sortCtorsDtors() {
|
|||||||
// If an input string is in the form of "foo.N" where N is a number,
|
// If an input string is in the form of "foo.N" where N is a number,
|
||||||
// return N. Otherwise, returns 65536, which is one greater than the
|
// return N. Otherwise, returns 65536, which is one greater than the
|
||||||
// lowest priority.
|
// lowest priority.
|
||||||
int elf::getPriority(StringRef s) {
|
int getPriority(StringRef s) {
|
||||||
size_t pos = s.rfind('.');
|
size_t pos = s.rfind('.');
|
||||||
if (pos == StringRef::npos)
|
if (pos == StringRef::npos)
|
||||||
return 65536;
|
return 65536;
|
||||||
@ -456,7 +455,7 @@ int elf::getPriority(StringRef s) {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<InputSection *> elf::getInputSections(OutputSection *os) {
|
std::vector<InputSection *> getInputSections(OutputSection *os) {
|
||||||
std::vector<InputSection *> ret;
|
std::vector<InputSection *> ret;
|
||||||
for (BaseCommand *base : os->sectionCommands)
|
for (BaseCommand *base : os->sectionCommands)
|
||||||
if (auto *isd = dyn_cast<InputSectionDescription>(base))
|
if (auto *isd = dyn_cast<InputSectionDescription>(base))
|
||||||
@ -497,3 +496,6 @@ template void OutputSection::maybeCompress<ELF32LE>();
|
|||||||
template void OutputSection::maybeCompress<ELF32BE>();
|
template void OutputSection::maybeCompress<ELF32BE>();
|
||||||
template void OutputSection::maybeCompress<ELF64LE>();
|
template void OutputSection::maybeCompress<ELF64LE>();
|
||||||
template void OutputSection::maybeCompress<ELF64BE>();
|
template void OutputSection::maybeCompress<ELF64BE>();
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -62,9 +62,8 @@ using namespace llvm::ELF;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
namespace elf {
|
||||||
|
|
||||||
static Optional<std::string> getLinkerScriptLocation(const Symbol &sym) {
|
static Optional<std::string> getLinkerScriptLocation(const Symbol &sym) {
|
||||||
for (BaseCommand *base : script->sectionCommands)
|
for (BaseCommand *base : script->sectionCommands)
|
||||||
if (auto *cmd = dyn_cast<SymbolAssignment>(base))
|
if (auto *cmd = dyn_cast<SymbolAssignment>(base))
|
||||||
@ -823,7 +822,7 @@ static void reportUndefinedSymbol(const UndefinedDiag &undef,
|
|||||||
error(msg);
|
error(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void elf::reportUndefinedSymbols() {
|
template <class ELFT> void reportUndefinedSymbols() {
|
||||||
// Find the first "undefined symbol" diagnostic for each diagnostic, and
|
// Find the first "undefined symbol" diagnostic for each diagnostic, and
|
||||||
// collect all "referenced from" lines at the first diagnostic.
|
// collect all "referenced from" lines at the first diagnostic.
|
||||||
DenseMap<Symbol *, UndefinedDiag *> firstRef;
|
DenseMap<Symbol *, UndefinedDiag *> firstRef;
|
||||||
@ -1405,7 +1404,7 @@ static void scanRelocs(InputSectionBase &sec, ArrayRef<RelTy> rels) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void elf::scanRelocations(InputSectionBase &s) {
|
template <class ELFT> void scanRelocations(InputSectionBase &s) {
|
||||||
if (s.areRelocsRela)
|
if (s.areRelocsRela)
|
||||||
scanRelocs<ELFT>(s, s.relas<ELFT>());
|
scanRelocs<ELFT>(s, s.relas<ELFT>());
|
||||||
else
|
else
|
||||||
@ -1832,11 +1831,14 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> outputSections) {
|
|||||||
return addressesChanged;
|
return addressesChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
template void elf::scanRelocations<ELF32LE>(InputSectionBase &);
|
template void scanRelocations<ELF32LE>(InputSectionBase &);
|
||||||
template void elf::scanRelocations<ELF32BE>(InputSectionBase &);
|
template void scanRelocations<ELF32BE>(InputSectionBase &);
|
||||||
template void elf::scanRelocations<ELF64LE>(InputSectionBase &);
|
template void scanRelocations<ELF64LE>(InputSectionBase &);
|
||||||
template void elf::scanRelocations<ELF64BE>(InputSectionBase &);
|
template void scanRelocations<ELF64BE>(InputSectionBase &);
|
||||||
template void elf::reportUndefinedSymbols<ELF32LE>();
|
template void reportUndefinedSymbols<ELF32LE>();
|
||||||
template void elf::reportUndefinedSymbols<ELF32BE>();
|
template void reportUndefinedSymbols<ELF32BE>();
|
||||||
template void elf::reportUndefinedSymbols<ELF64LE>();
|
template void reportUndefinedSymbols<ELF64LE>();
|
||||||
template void elf::reportUndefinedSymbols<ELF64BE>();
|
template void reportUndefinedSymbols<ELF64BE>();
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -36,9 +36,9 @@
|
|||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
|
||||||
|
|
||||||
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
// Returns a whole line containing the current token.
|
// Returns a whole line containing the current token.
|
||||||
StringRef ScriptLexer::getLine() {
|
StringRef ScriptLexer::getLine() {
|
||||||
StringRef s = getCurrentMB().getBuffer();
|
StringRef s = getCurrentMB().getBuffer();
|
||||||
@ -298,3 +298,6 @@ MemoryBufferRef ScriptLexer::getCurrentMB() {
|
|||||||
return mb;
|
return mb;
|
||||||
llvm_unreachable("getCurrentMB: failed to find a token");
|
llvm_unreachable("getCurrentMB: failed to find a token");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -37,9 +37,9 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
|
||||||
|
|
||||||
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
namespace {
|
namespace {
|
||||||
class ScriptParser final : ScriptLexer {
|
class ScriptParser final : ScriptLexer {
|
||||||
public:
|
public:
|
||||||
@ -1268,7 +1268,7 @@ Expr ScriptParser::readPrimary() {
|
|||||||
return [=] { return cmd->size; };
|
return [=] { return cmd->size; };
|
||||||
}
|
}
|
||||||
if (tok == "SIZEOF_HEADERS")
|
if (tok == "SIZEOF_HEADERS")
|
||||||
return [=] { return elf::getHeaderSize(); };
|
return [=] { return getHeaderSize(); };
|
||||||
|
|
||||||
// Tok is the dot.
|
// Tok is the dot.
|
||||||
if (tok == ".")
|
if (tok == ".")
|
||||||
@ -1511,18 +1511,19 @@ std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
|
|||||||
return {flags, negFlags};
|
return {flags, negFlags};
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf::readLinkerScript(MemoryBufferRef mb) {
|
void readLinkerScript(MemoryBufferRef mb) {
|
||||||
ScriptParser(mb).readLinkerScript();
|
ScriptParser(mb).readLinkerScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf::readVersionScript(MemoryBufferRef mb) {
|
void readVersionScript(MemoryBufferRef mb) {
|
||||||
ScriptParser(mb).readVersionScript();
|
ScriptParser(mb).readVersionScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf::readDynamicList(MemoryBufferRef mb) {
|
void readDynamicList(MemoryBufferRef mb) { ScriptParser(mb).readDynamicList(); }
|
||||||
ScriptParser(mb).readDynamicList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void elf::readDefsym(StringRef name, MemoryBufferRef mb) {
|
void readDefsym(StringRef name, MemoryBufferRef mb) {
|
||||||
ScriptParser(mb).readDefsym(name);
|
ScriptParser(mb).readDefsym(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -27,10 +27,9 @@ using namespace llvm;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
namespace elf {
|
||||||
|
SymbolTable *symtab;
|
||||||
SymbolTable *elf::symtab;
|
|
||||||
|
|
||||||
void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
|
void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
|
||||||
// Swap symbols as instructed by -wrap.
|
// Swap symbols as instructed by -wrap.
|
||||||
@ -265,3 +264,6 @@ void SymbolTable::scanVersionScript() {
|
|||||||
// --dynamic-list.
|
// --dynamic-list.
|
||||||
handleDynamicList();
|
handleDynamicList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -23,9 +23,20 @@ using namespace llvm;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
// Returns a symbol for an error message.
|
||||||
|
static std::string demangle(StringRef symName) {
|
||||||
|
if (elf::config->demangle)
|
||||||
|
return demangleItanium(symName);
|
||||||
|
return symName;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toString(const elf::Symbol &b) { return demangle(b.getName()); }
|
||||||
|
std::string toELFString(const Archive::Symbol &b) {
|
||||||
|
return demangle(b.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace elf {
|
||||||
Defined *ElfSym::bss;
|
Defined *ElfSym::bss;
|
||||||
Defined *ElfSym::etext1;
|
Defined *ElfSym::etext1;
|
||||||
Defined *ElfSym::etext2;
|
Defined *ElfSym::etext2;
|
||||||
@ -42,19 +53,6 @@ Defined *ElfSym::relaIpltEnd;
|
|||||||
Defined *ElfSym::riscvGlobalPointer;
|
Defined *ElfSym::riscvGlobalPointer;
|
||||||
Defined *ElfSym::tlsModuleBase;
|
Defined *ElfSym::tlsModuleBase;
|
||||||
|
|
||||||
// Returns a symbol for an error message.
|
|
||||||
static std::string demangle(StringRef symName) {
|
|
||||||
if (config->demangle)
|
|
||||||
return demangleItanium(symName);
|
|
||||||
return symName;
|
|
||||||
}
|
|
||||||
namespace lld {
|
|
||||||
std::string toString(const Symbol &b) { return demangle(b.getName()); }
|
|
||||||
std::string toELFString(const Archive::Symbol &b) {
|
|
||||||
return demangle(b.getName());
|
|
||||||
}
|
|
||||||
} // namespace lld
|
|
||||||
|
|
||||||
static uint64_t getSymVA(const Symbol &sym, int64_t &addend) {
|
static uint64_t getSymVA(const Symbol &sym, int64_t &addend) {
|
||||||
switch (sym.kind()) {
|
switch (sym.kind()) {
|
||||||
case Symbol::DefinedKind: {
|
case Symbol::DefinedKind: {
|
||||||
@ -298,7 +296,7 @@ bool Symbol::includeInDynsym() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Print out a log message for --trace-symbol.
|
// Print out a log message for --trace-symbol.
|
||||||
void elf::printTraceSymbol(const Symbol *sym) {
|
void printTraceSymbol(const Symbol *sym) {
|
||||||
std::string s;
|
std::string s;
|
||||||
if (sym->isUndefined())
|
if (sym->isUndefined())
|
||||||
s = ": reference to ";
|
s = ": reference to ";
|
||||||
@ -314,7 +312,7 @@ void elf::printTraceSymbol(const Symbol *sym) {
|
|||||||
message(toString(sym->file) + s + sym->getName());
|
message(toString(sym->file) + s + sym->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf::maybeWarnUnorderableSymbol(const Symbol *sym) {
|
void maybeWarnUnorderableSymbol(const Symbol *sym) {
|
||||||
if (!config->warnSymbolOrdering)
|
if (!config->warnSymbolOrdering)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -655,3 +653,6 @@ void Symbol::resolveShared(const SharedSymbol &other) {
|
|||||||
referenced = true;
|
referenced = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -21,6 +21,13 @@
|
|||||||
#include "llvm/Object/ELF.h"
|
#include "llvm/Object/ELF.h"
|
||||||
|
|
||||||
namespace lld {
|
namespace lld {
|
||||||
|
std::string toString(const elf::Symbol &);
|
||||||
|
|
||||||
|
// There are two different ways to convert an Archive::Symbol to a string:
|
||||||
|
// One for Microsoft name mangling and one for Itanium name mangling.
|
||||||
|
// Call the functions toCOFFString and toELFString, not just toString.
|
||||||
|
std::string toELFString(const llvm::object::Archive::Symbol &);
|
||||||
|
|
||||||
namespace elf {
|
namespace elf {
|
||||||
class CommonSymbol;
|
class CommonSymbol;
|
||||||
class Defined;
|
class Defined;
|
||||||
@ -30,16 +37,6 @@ class LazyObject;
|
|||||||
class SharedSymbol;
|
class SharedSymbol;
|
||||||
class Symbol;
|
class Symbol;
|
||||||
class Undefined;
|
class Undefined;
|
||||||
} // namespace elf
|
|
||||||
|
|
||||||
std::string toString(const elf::Symbol &);
|
|
||||||
|
|
||||||
// There are two different ways to convert an Archive::Symbol to a string:
|
|
||||||
// One for Microsoft name mangling and one for Itanium name mangling.
|
|
||||||
// Call the functions toCOFFString and toELFString, not just toString.
|
|
||||||
std::string toELFString(const elf::Archive::Symbol &);
|
|
||||||
|
|
||||||
namespace elf {
|
|
||||||
|
|
||||||
// This is a StringRef-like container that doesn't run strlen().
|
// This is a StringRef-like container that doesn't run strlen().
|
||||||
//
|
//
|
||||||
|
@ -45,13 +45,12 @@ using namespace llvm::ELF;
|
|||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::support;
|
using namespace llvm::support;
|
||||||
|
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
|
||||||
|
|
||||||
using llvm::support::endian::read32le;
|
using llvm::support::endian::read32le;
|
||||||
using llvm::support::endian::write32le;
|
using llvm::support::endian::write32le;
|
||||||
using llvm::support::endian::write64le;
|
using llvm::support::endian::write64le;
|
||||||
|
|
||||||
|
namespace lld {
|
||||||
|
namespace elf {
|
||||||
constexpr size_t MergeNoTailSection::numShards;
|
constexpr size_t MergeNoTailSection::numShards;
|
||||||
|
|
||||||
static uint64_t readUint(uint8_t *buf) {
|
static uint64_t readUint(uint8_t *buf) {
|
||||||
@ -82,7 +81,7 @@ static ArrayRef<uint8_t> getVersion() {
|
|||||||
// With this feature, you can identify LLD-generated binaries easily
|
// With this feature, you can identify LLD-generated binaries easily
|
||||||
// by "readelf --string-dump .comment <file>".
|
// by "readelf --string-dump .comment <file>".
|
||||||
// The returned object is a mergeable string section.
|
// The returned object is a mergeable string section.
|
||||||
MergeInputSection *elf::createCommentSection() {
|
MergeInputSection *createCommentSection() {
|
||||||
return make<MergeInputSection>(SHF_MERGE | SHF_STRINGS, SHT_PROGBITS, 1,
|
return make<MergeInputSection>(SHF_MERGE | SHF_STRINGS, SHT_PROGBITS, 1,
|
||||||
getVersion(), ".comment");
|
getVersion(), ".comment");
|
||||||
}
|
}
|
||||||
@ -138,7 +137,7 @@ MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {
|
|||||||
flags.ases |= s->ases;
|
flags.ases |= s->ases;
|
||||||
flags.flags1 |= s->flags1;
|
flags.flags1 |= s->flags1;
|
||||||
flags.flags2 |= s->flags2;
|
flags.flags2 |= s->flags2;
|
||||||
flags.fp_abi = elf::getMipsFpAbiFlag(flags.fp_abi, s->fp_abi, filename);
|
flags.fp_abi = getMipsFpAbiFlag(flags.fp_abi, s->fp_abi, filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (create)
|
if (create)
|
||||||
@ -252,7 +251,7 @@ MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() {
|
|||||||
return make<MipsReginfoSection<ELFT>>(reginfo);
|
return make<MipsReginfoSection<ELFT>>(reginfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
InputSection *elf::createInterpSection() {
|
InputSection *createInterpSection() {
|
||||||
// StringSaver guarantees that the returned string ends with '\0'.
|
// StringSaver guarantees that the returned string ends with '\0'.
|
||||||
StringRef s = saver.save(config->dynamicLinker);
|
StringRef s = saver.save(config->dynamicLinker);
|
||||||
ArrayRef<uint8_t> contents = {(const uint8_t *)s.data(), s.size() + 1};
|
ArrayRef<uint8_t> contents = {(const uint8_t *)s.data(), s.size() + 1};
|
||||||
@ -261,8 +260,8 @@ InputSection *elf::createInterpSection() {
|
|||||||
".interp");
|
".interp");
|
||||||
}
|
}
|
||||||
|
|
||||||
Defined *elf::addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
|
Defined *addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
|
||||||
uint64_t size, InputSectionBase §ion) {
|
uint64_t size, InputSectionBase §ion) {
|
||||||
auto *s = make<Defined>(section.file, name, STB_LOCAL, STV_DEFAULT, type,
|
auto *s = make<Defined>(section.file, name, STB_LOCAL, STV_DEFAULT, type,
|
||||||
value, size, §ion);
|
value, size, §ion);
|
||||||
if (in.symTab)
|
if (in.symTab)
|
||||||
@ -1274,7 +1273,7 @@ static uint64_t addPltRelSz() {
|
|||||||
|
|
||||||
// Add remaining entries to complete .dynamic contents.
|
// Add remaining entries to complete .dynamic contents.
|
||||||
template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
|
template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
|
||||||
elf::Partition &part = getPartition();
|
Partition &part = getPartition();
|
||||||
bool isMain = part.name.empty();
|
bool isMain = part.name.empty();
|
||||||
|
|
||||||
for (StringRef s : config->filterList)
|
for (StringRef s : config->filterList)
|
||||||
@ -2940,7 +2939,7 @@ bool VersionTableSection::isNeeded() const {
|
|||||||
return getPartition().verDef || getPartition().verNeed->isNeeded();
|
return getPartition().verDef || getPartition().verNeed->isNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf::addVerneed(Symbol *ss) {
|
void addVerneed(Symbol *ss) {
|
||||||
auto &file = cast<SharedFile>(*ss->file);
|
auto &file = cast<SharedFile>(*ss->file);
|
||||||
if (ss->verdefIndex == VER_NDX_GLOBAL) {
|
if (ss->verdefIndex == VER_NDX_GLOBAL) {
|
||||||
ss->versionId = VER_NDX_GLOBAL;
|
ss->versionId = VER_NDX_GLOBAL;
|
||||||
@ -3123,16 +3122,16 @@ void MergeNoTailSection::finalizeContents() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
MergeSyntheticSection *elf::createMergeSynthetic(StringRef name, uint32_t type,
|
MergeSyntheticSection *createMergeSynthetic(StringRef name, uint32_t type,
|
||||||
uint64_t flags,
|
uint64_t flags,
|
||||||
uint32_t alignment) {
|
uint32_t alignment) {
|
||||||
bool shouldTailMerge = (flags & SHF_STRINGS) && config->optimize >= 2;
|
bool shouldTailMerge = (flags & SHF_STRINGS) && config->optimize >= 2;
|
||||||
if (shouldTailMerge)
|
if (shouldTailMerge)
|
||||||
return make<MergeTailSection>(name, type, flags, alignment);
|
return make<MergeTailSection>(name, type, flags, alignment);
|
||||||
return make<MergeNoTailSection>(name, type, flags, alignment);
|
return make<MergeNoTailSection>(name, type, flags, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void elf::splitSections() {
|
template <class ELFT> void splitSections() {
|
||||||
// splitIntoPieces needs to be called on each MergeInputSection
|
// splitIntoPieces needs to be called on each MergeInputSection
|
||||||
// before calling finalizeContents().
|
// before calling finalizeContents().
|
||||||
parallelForEach(inputSections, [](InputSectionBase *sec) {
|
parallelForEach(inputSections, [](InputSectionBase *sec) {
|
||||||
@ -3486,7 +3485,7 @@ static uint8_t getAbiVersion() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ELFT> void elf::writeEhdr(uint8_t *buf, Partition &part) {
|
template <typename ELFT> void writeEhdr(uint8_t *buf, Partition &part) {
|
||||||
// For executable segments, the trap instructions are written before writing
|
// For executable segments, the trap instructions are written before writing
|
||||||
// the header. Setting Elf header bytes to zero ensures that any unused bytes
|
// the header. Setting Elf header bytes to zero ensures that any unused bytes
|
||||||
// in header are zero-cleared, instead of having trap instructions.
|
// in header are zero-cleared, instead of having trap instructions.
|
||||||
@ -3512,7 +3511,7 @@ template <typename ELFT> void elf::writeEhdr(uint8_t *buf, Partition &part) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ELFT> void elf::writePhdrs(uint8_t *buf, Partition &part) {
|
template <typename ELFT> void writePhdrs(uint8_t *buf, Partition &part) {
|
||||||
// Write the program header table.
|
// Write the program header table.
|
||||||
auto *hBuf = reinterpret_cast<typename ELFT::Phdr *>(buf);
|
auto *hBuf = reinterpret_cast<typename ELFT::Phdr *>(buf);
|
||||||
for (PhdrEntry *p : part.phdrs) {
|
for (PhdrEntry *p : part.phdrs) {
|
||||||
@ -3587,87 +3586,90 @@ void PartitionIndexSection::writeTo(uint8_t *buf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InStruct elf::in;
|
InStruct in;
|
||||||
|
|
||||||
std::vector<Partition> elf::partitions;
|
std::vector<Partition> partitions;
|
||||||
Partition *elf::mainPart;
|
Partition *mainPart;
|
||||||
|
|
||||||
template GdbIndexSection *GdbIndexSection::create<ELF32LE>();
|
template GdbIndexSection *GdbIndexSection::create<ELF32LE>();
|
||||||
template GdbIndexSection *GdbIndexSection::create<ELF32BE>();
|
template GdbIndexSection *GdbIndexSection::create<ELF32BE>();
|
||||||
template GdbIndexSection *GdbIndexSection::create<ELF64LE>();
|
template GdbIndexSection *GdbIndexSection::create<ELF64LE>();
|
||||||
template GdbIndexSection *GdbIndexSection::create<ELF64BE>();
|
template GdbIndexSection *GdbIndexSection::create<ELF64BE>();
|
||||||
|
|
||||||
template void elf::splitSections<ELF32LE>();
|
template void splitSections<ELF32LE>();
|
||||||
template void elf::splitSections<ELF32BE>();
|
template void splitSections<ELF32BE>();
|
||||||
template void elf::splitSections<ELF64LE>();
|
template void splitSections<ELF64LE>();
|
||||||
template void elf::splitSections<ELF64BE>();
|
template void splitSections<ELF64BE>();
|
||||||
|
|
||||||
template void PltSection::addEntry<ELF32LE>(Symbol &Sym);
|
template void PltSection::addEntry<ELF32LE>(Symbol &Sym);
|
||||||
template void PltSection::addEntry<ELF32BE>(Symbol &Sym);
|
template void PltSection::addEntry<ELF32BE>(Symbol &Sym);
|
||||||
template void PltSection::addEntry<ELF64LE>(Symbol &Sym);
|
template void PltSection::addEntry<ELF64LE>(Symbol &Sym);
|
||||||
template void PltSection::addEntry<ELF64BE>(Symbol &Sym);
|
template void PltSection::addEntry<ELF64BE>(Symbol &Sym);
|
||||||
|
|
||||||
template class elf::MipsAbiFlagsSection<ELF32LE>;
|
template class MipsAbiFlagsSection<ELF32LE>;
|
||||||
template class elf::MipsAbiFlagsSection<ELF32BE>;
|
template class MipsAbiFlagsSection<ELF32BE>;
|
||||||
template class elf::MipsAbiFlagsSection<ELF64LE>;
|
template class MipsAbiFlagsSection<ELF64LE>;
|
||||||
template class elf::MipsAbiFlagsSection<ELF64BE>;
|
template class MipsAbiFlagsSection<ELF64BE>;
|
||||||
|
|
||||||
template class elf::MipsOptionsSection<ELF32LE>;
|
template class MipsOptionsSection<ELF32LE>;
|
||||||
template class elf::MipsOptionsSection<ELF32BE>;
|
template class MipsOptionsSection<ELF32BE>;
|
||||||
template class elf::MipsOptionsSection<ELF64LE>;
|
template class MipsOptionsSection<ELF64LE>;
|
||||||
template class elf::MipsOptionsSection<ELF64BE>;
|
template class MipsOptionsSection<ELF64BE>;
|
||||||
|
|
||||||
template class elf::MipsReginfoSection<ELF32LE>;
|
template class MipsReginfoSection<ELF32LE>;
|
||||||
template class elf::MipsReginfoSection<ELF32BE>;
|
template class MipsReginfoSection<ELF32BE>;
|
||||||
template class elf::MipsReginfoSection<ELF64LE>;
|
template class MipsReginfoSection<ELF64LE>;
|
||||||
template class elf::MipsReginfoSection<ELF64BE>;
|
template class MipsReginfoSection<ELF64BE>;
|
||||||
|
|
||||||
template class elf::DynamicSection<ELF32LE>;
|
template class DynamicSection<ELF32LE>;
|
||||||
template class elf::DynamicSection<ELF32BE>;
|
template class DynamicSection<ELF32BE>;
|
||||||
template class elf::DynamicSection<ELF64LE>;
|
template class DynamicSection<ELF64LE>;
|
||||||
template class elf::DynamicSection<ELF64BE>;
|
template class DynamicSection<ELF64BE>;
|
||||||
|
|
||||||
template class elf::RelocationSection<ELF32LE>;
|
template class RelocationSection<ELF32LE>;
|
||||||
template class elf::RelocationSection<ELF32BE>;
|
template class RelocationSection<ELF32BE>;
|
||||||
template class elf::RelocationSection<ELF64LE>;
|
template class RelocationSection<ELF64LE>;
|
||||||
template class elf::RelocationSection<ELF64BE>;
|
template class RelocationSection<ELF64BE>;
|
||||||
|
|
||||||
template class elf::AndroidPackedRelocationSection<ELF32LE>;
|
template class AndroidPackedRelocationSection<ELF32LE>;
|
||||||
template class elf::AndroidPackedRelocationSection<ELF32BE>;
|
template class AndroidPackedRelocationSection<ELF32BE>;
|
||||||
template class elf::AndroidPackedRelocationSection<ELF64LE>;
|
template class AndroidPackedRelocationSection<ELF64LE>;
|
||||||
template class elf::AndroidPackedRelocationSection<ELF64BE>;
|
template class AndroidPackedRelocationSection<ELF64BE>;
|
||||||
|
|
||||||
template class elf::RelrSection<ELF32LE>;
|
template class RelrSection<ELF32LE>;
|
||||||
template class elf::RelrSection<ELF32BE>;
|
template class RelrSection<ELF32BE>;
|
||||||
template class elf::RelrSection<ELF64LE>;
|
template class RelrSection<ELF64LE>;
|
||||||
template class elf::RelrSection<ELF64BE>;
|
template class RelrSection<ELF64BE>;
|
||||||
|
|
||||||
template class elf::SymbolTableSection<ELF32LE>;
|
template class SymbolTableSection<ELF32LE>;
|
||||||
template class elf::SymbolTableSection<ELF32BE>;
|
template class SymbolTableSection<ELF32BE>;
|
||||||
template class elf::SymbolTableSection<ELF64LE>;
|
template class SymbolTableSection<ELF64LE>;
|
||||||
template class elf::SymbolTableSection<ELF64BE>;
|
template class SymbolTableSection<ELF64BE>;
|
||||||
|
|
||||||
template class elf::VersionNeedSection<ELF32LE>;
|
template class VersionNeedSection<ELF32LE>;
|
||||||
template class elf::VersionNeedSection<ELF32BE>;
|
template class VersionNeedSection<ELF32BE>;
|
||||||
template class elf::VersionNeedSection<ELF64LE>;
|
template class VersionNeedSection<ELF64LE>;
|
||||||
template class elf::VersionNeedSection<ELF64BE>;
|
template class VersionNeedSection<ELF64BE>;
|
||||||
|
|
||||||
template void elf::writeEhdr<ELF32LE>(uint8_t *Buf, Partition &Part);
|
template void writeEhdr<ELF32LE>(uint8_t *Buf, Partition &Part);
|
||||||
template void elf::writeEhdr<ELF32BE>(uint8_t *Buf, Partition &Part);
|
template void writeEhdr<ELF32BE>(uint8_t *Buf, Partition &Part);
|
||||||
template void elf::writeEhdr<ELF64LE>(uint8_t *Buf, Partition &Part);
|
template void writeEhdr<ELF64LE>(uint8_t *Buf, Partition &Part);
|
||||||
template void elf::writeEhdr<ELF64BE>(uint8_t *Buf, Partition &Part);
|
template void writeEhdr<ELF64BE>(uint8_t *Buf, Partition &Part);
|
||||||
|
|
||||||
template void elf::writePhdrs<ELF32LE>(uint8_t *Buf, Partition &Part);
|
template void writePhdrs<ELF32LE>(uint8_t *Buf, Partition &Part);
|
||||||
template void elf::writePhdrs<ELF32BE>(uint8_t *Buf, Partition &Part);
|
template void writePhdrs<ELF32BE>(uint8_t *Buf, Partition &Part);
|
||||||
template void elf::writePhdrs<ELF64LE>(uint8_t *Buf, Partition &Part);
|
template void writePhdrs<ELF64LE>(uint8_t *Buf, Partition &Part);
|
||||||
template void elf::writePhdrs<ELF64BE>(uint8_t *Buf, Partition &Part);
|
template void writePhdrs<ELF64BE>(uint8_t *Buf, Partition &Part);
|
||||||
|
|
||||||
template class elf::PartitionElfHeaderSection<ELF32LE>;
|
template class PartitionElfHeaderSection<ELF32LE>;
|
||||||
template class elf::PartitionElfHeaderSection<ELF32BE>;
|
template class PartitionElfHeaderSection<ELF32BE>;
|
||||||
template class elf::PartitionElfHeaderSection<ELF64LE>;
|
template class PartitionElfHeaderSection<ELF64LE>;
|
||||||
template class elf::PartitionElfHeaderSection<ELF64BE>;
|
template class PartitionElfHeaderSection<ELF64BE>;
|
||||||
|
|
||||||
template class elf::PartitionProgramHeadersSection<ELF32LE>;
|
template class PartitionProgramHeadersSection<ELF32LE>;
|
||||||
template class elf::PartitionProgramHeadersSection<ELF32BE>;
|
template class PartitionProgramHeadersSection<ELF32BE>;
|
||||||
template class elf::PartitionProgramHeadersSection<ELF64LE>;
|
template class PartitionProgramHeadersSection<ELF64LE>;
|
||||||
template class elf::PartitionProgramHeadersSection<ELF64BE>;
|
template class PartitionProgramHeadersSection<ELF64BE>;
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -34,19 +34,19 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
using namespace llvm::ELF;
|
using namespace llvm::ELF;
|
||||||
using namespace lld;
|
|
||||||
using namespace lld::elf;
|
|
||||||
|
|
||||||
const TargetInfo *elf::target;
|
namespace lld {
|
||||||
|
std::string toString(elf::RelType type) {
|
||||||
std::string lld::toString(RelType type) {
|
|
||||||
StringRef s = getELFRelocationTypeName(elf::config->emachine, type);
|
StringRef s = getELFRelocationTypeName(elf::config->emachine, type);
|
||||||
if (s == "Unknown")
|
if (s == "Unknown")
|
||||||
return ("Unknown (" + Twine(type) + ")").str();
|
return ("Unknown (" + Twine(type) + ")").str();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo *elf::getTarget() {
|
namespace elf {
|
||||||
|
const TargetInfo *target;
|
||||||
|
|
||||||
|
TargetInfo *getTarget() {
|
||||||
switch (config->emachine) {
|
switch (config->emachine) {
|
||||||
case EM_386:
|
case EM_386:
|
||||||
case EM_IAMCU:
|
case EM_IAMCU:
|
||||||
@ -103,7 +103,7 @@ template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
|
ErrorPlace getErrorPlace(const uint8_t *loc) {
|
||||||
switch (config->ekind) {
|
switch (config->ekind) {
|
||||||
case ELF32LEKind:
|
case ELF32LEKind:
|
||||||
return getErrPlace<ELF32LE>(loc);
|
return getErrPlace<ELF32LE>(loc);
|
||||||
@ -179,3 +179,6 @@ uint64_t TargetInfo::getImageBase() const {
|
|||||||
return *config->imageBase;
|
return *config->imageBase;
|
||||||
return config->isPic ? 0 : defaultImageBase;
|
return config->isPic ? 0 : defaultImageBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
@ -36,9 +36,8 @@ using namespace llvm::object;
|
|||||||
using namespace llvm::support;
|
using namespace llvm::support;
|
||||||
using namespace llvm::support::endian;
|
using namespace llvm::support::endian;
|
||||||
|
|
||||||
using namespace lld;
|
namespace lld {
|
||||||
using namespace lld::elf;
|
namespace elf {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// The writer writes a SymbolTable result to a file.
|
// The writer writes a SymbolTable result to a file.
|
||||||
template <class ELFT> class Writer {
|
template <class ELFT> class Writer {
|
||||||
@ -92,7 +91,7 @@ static bool isSectionPrefix(StringRef prefix, StringRef name) {
|
|||||||
return name.startswith(prefix) || name == prefix.drop_back();
|
return name.startswith(prefix) || name == prefix.drop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef elf::getOutputSectionName(const InputSectionBase *s) {
|
StringRef getOutputSectionName(const InputSectionBase *s) {
|
||||||
if (config->relocatable)
|
if (config->relocatable)
|
||||||
return s->name;
|
return s->name;
|
||||||
|
|
||||||
@ -140,7 +139,7 @@ static bool needsInterpSection() {
|
|||||||
script->needsInterpSection();
|
script->needsInterpSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); }
|
template <class ELFT> void writeResult() { Writer<ELFT>().run(); }
|
||||||
|
|
||||||
static void removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrs) {
|
static void removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrs) {
|
||||||
llvm::erase_if(phdrs, [&](const PhdrEntry *p) {
|
llvm::erase_if(phdrs, [&](const PhdrEntry *p) {
|
||||||
@ -153,7 +152,7 @@ static void removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrs) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf::copySectionsIntoPartitions() {
|
void copySectionsIntoPartitions() {
|
||||||
std::vector<InputSectionBase *> newSections;
|
std::vector<InputSectionBase *> newSections;
|
||||||
for (unsigned part = 2; part != partitions.size() + 1; ++part) {
|
for (unsigned part = 2; part != partitions.size() + 1; ++part) {
|
||||||
for (InputSectionBase *s : inputSections) {
|
for (InputSectionBase *s : inputSections) {
|
||||||
@ -175,7 +174,7 @@ void elf::copySectionsIntoPartitions() {
|
|||||||
newSections.end());
|
newSections.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf::combineEhSections() {
|
void combineEhSections() {
|
||||||
for (InputSectionBase *&s : inputSections) {
|
for (InputSectionBase *&s : inputSections) {
|
||||||
// Ignore dead sections and the partition end marker (.part.end),
|
// Ignore dead sections and the partition end marker (.part.end),
|
||||||
// whose partition number is out of bounds.
|
// whose partition number is out of bounds.
|
||||||
@ -216,7 +215,7 @@ static Defined *addAbsolute(StringRef name) {
|
|||||||
|
|
||||||
// The linker is expected to define some symbols depending on
|
// The linker is expected to define some symbols depending on
|
||||||
// the linking result. This function defines such symbols.
|
// the linking result. This function defines such symbols.
|
||||||
void elf::addReservedSymbols() {
|
void addReservedSymbols() {
|
||||||
if (config->emachine == EM_MIPS) {
|
if (config->emachine == EM_MIPS) {
|
||||||
// Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
|
// Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
|
||||||
// so that it points to an absolute address which by default is relative
|
// so that it points to an absolute address which by default is relative
|
||||||
@ -309,7 +308,7 @@ static OutputSection *findSection(StringRef name, unsigned partition = 1) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void elf::createSyntheticSections() {
|
template <class ELFT> void createSyntheticSections() {
|
||||||
// Initialize all pointers with NULL. This is needed because
|
// Initialize all pointers with NULL. This is needed because
|
||||||
// you can call lld::elf::main more than once as a library.
|
// you can call lld::elf::main more than once as a library.
|
||||||
memset(&Out::first, 0, sizeof(Out));
|
memset(&Out::first, 0, sizeof(Out));
|
||||||
@ -2737,12 +2736,15 @@ template <class ELFT> void Writer<ELFT>::writeBuildId() {
|
|||||||
part.buildId->writeBuildId(buildId);
|
part.buildId->writeBuildId(buildId);
|
||||||
}
|
}
|
||||||
|
|
||||||
template void elf::createSyntheticSections<ELF32LE>();
|
template void createSyntheticSections<ELF32LE>();
|
||||||
template void elf::createSyntheticSections<ELF32BE>();
|
template void createSyntheticSections<ELF32BE>();
|
||||||
template void elf::createSyntheticSections<ELF64LE>();
|
template void createSyntheticSections<ELF64LE>();
|
||||||
template void elf::createSyntheticSections<ELF64BE>();
|
template void createSyntheticSections<ELF64BE>();
|
||||||
|
|
||||||
template void elf::writeResult<ELF32LE>();
|
template void writeResult<ELF32LE>();
|
||||||
template void elf::writeResult<ELF32BE>();
|
template void writeResult<ELF32BE>();
|
||||||
template void elf::writeResult<ELF64LE>();
|
template void writeResult<ELF64LE>();
|
||||||
template void elf::writeResult<ELF64BE>();
|
template void writeResult<ELF64BE>();
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace lld
|
||||||
|
Loading…
x
Reference in New Issue
Block a user