Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/eld/Target/GNULDBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,7 @@ class GNULDBackend {
virtual void addTargetSpecificSegments();

void addSectionInfo(LDSymbol *symbol, ELFSection *section);
LDSymbol *defineGlobalOffsetTableSymbol();

/// Returns the name of the common symbol associated with the section
/// 'commonSection'.
Expand Down
63 changes: 21 additions & 42 deletions lib/Target/AArch64/AArch64LDBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ using namespace llvm;
//===----------------------------------------------------------------------===//
// AArch64LDBackend
//===----------------------------------------------------------------------===//
AArch64LDBackend::AArch64LDBackend(eld::Module &pModule,
TargetInfo *pInfo)
AArch64LDBackend::AArch64LDBackend(eld::Module &pModule, TargetInfo *pInfo)
: GNULDBackend(pModule, pInfo), m_pErrata843419Factory(nullptr),
m_pAArch64ErrataIslandFactory(nullptr), m_pRelocator(nullptr),
m_pDynamic(nullptr), m_pIRelativeStart(nullptr), m_pIRelativeEnd(nullptr),
Expand Down Expand Up @@ -109,24 +108,8 @@ void AArch64LDBackend::initTargetSections(ObjectBuilder &pBuilder) {
}

void AArch64LDBackend::initTargetSymbols() {
// Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
// same name in input
auto SymbolName = "_GLOBAL_OFFSET_TABLE_";
if (LinkerConfig::Object != config().codeGenType()) {
m_pGOTSymbol =
m_Module.getIRBuilder()
->addSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
m_Module.getInternalInput(Module::Script), SymbolName,
ResolveInfo::Object, ResolveInfo::Define, ResolveInfo::Local,
0x0, // size
0x0, // value
FragmentRef::null(), ResolveInfo::Hidden);
if (m_Module.getConfig().options().isSymbolTracingRequested() &&
m_Module.getConfig().options().traceSymbol(SymbolName))
config().raise(Diag::target_specific_symbol) << SymbolName;
if (m_pGOTSymbol)
m_pGOTSymbol->setShouldIgnore(false);
}
if (LinkerConfig::Object != config().codeGenType())
m_pGOTSymbol = defineGlobalOffsetTableSymbol();
}

bool AArch64LDBackend::initRelocator() {
Expand All @@ -136,8 +119,7 @@ bool AArch64LDBackend::initRelocator() {
return true;
}

bool AArch64LDBackend::processInputFiles(
std::vector<InputFile *> &Inputs) {
bool AArch64LDBackend::processInputFiles(std::vector<InputFile *> &Inputs) {
if (!m_pGPF)
return config().getDiagEngine()->diagnose();
for (auto &I : Inputs) {
Expand Down Expand Up @@ -220,8 +202,7 @@ void AArch64LDBackend::doPreLayout() {
m_ptbss = m_Module.getScript().sectionMap().find(".tbss");
}

void AArch64LDBackend::initSegmentFromLinkerScript(
ELFSegment *pSegment) {
void AArch64LDBackend::initSegmentFromLinkerScript(ELFSegment *pSegment) {
auto sect = pSegment->begin(), sectEnd = pSegment->end();
bool isPrevBSS = false;
bool hasMixedBSS = false;
Expand Down Expand Up @@ -260,8 +241,8 @@ void AArch64LDBackend::initSegmentFromLinkerScript(

AArch64ELFDynamic *AArch64LDBackend::dynamic() { return m_pDynamic; }

unsigned int AArch64LDBackend::getTargetSectionOrder(
const ELFSection &pSectHdr) const {
unsigned int
AArch64LDBackend::getTargetSectionOrder(const ELFSection &pSectHdr) const {
if (pSectHdr.name() == ".got") {
if (config().options().hasNow())
return SHO_RELRO;
Expand Down Expand Up @@ -349,9 +330,8 @@ void AArch64LDBackend::mayBeRelax(int pass, bool &pFinished) {
}

// Return whether this is a 3-insn erratum sequence.
bool AArch64LDBackend::isErratum843419Sequence(uint32_t insn1,
uint32_t insn2,
uint32_t insn3) {
bool AArch64LDBackend::isErratum843419Sequence(uint32_t insn1, uint32_t insn2,
uint32_t insn3) {
unsigned rt1, rt2;
bool load, pair;

Expand Down Expand Up @@ -462,7 +442,7 @@ bool AArch64LDBackend::scanErrata843419() {
}

void AArch64LDBackend::createErratum843419Stub(Fragment *frag,
uint32_t offset) {
uint32_t offset) {
BranchIsland *branchIsland = m_pErrata843419Factory->create(
frag, offset, *m_Module.getIRBuilder(), *m_pAArch64ErrataIslandFactory);
switch (config().options().getStripSymbolMode()) {
Expand Down Expand Up @@ -645,9 +625,9 @@ bool AArch64LDBackend::ltoNeedAssembler() {
return true;
}

bool AArch64LDBackend::ltoCallExternalAssembler(
const std::string &Input, std::string RelocModel,
const std::string &Output) {
bool AArch64LDBackend::ltoCallExternalAssembler(const std::string &Input,
std::string RelocModel,
const std::string &Output) {
bool traceLTO = config().options().traceLTO();

// Invoke assembler.
Expand Down Expand Up @@ -712,10 +692,8 @@ bool AArch64LDBackend::ltoCallExternalAssembler(
}

// Create GOT entry.
AArch64GOT *AArch64LDBackend::createGOT(GOT::GOTType T,
ELFObjectFile *Obj,
ResolveInfo *R,
bool SkipPLTRef) {
AArch64GOT *AArch64LDBackend::createGOT(GOT::GOTType T, ELFObjectFile *Obj,
ResolveInfo *R, bool SkipPLTRef) {

if (R != nullptr && ((config().options().isSymbolTracingRequested() &&
config().options().traceSymbol(*R)) ||
Expand Down Expand Up @@ -827,7 +805,8 @@ void AArch64LDBackend::recordPLT(ResolveInfo *I, AArch64PLT *P) {
m_PLTMap[I] = P;
}

Relocation *AArch64LDBackend::findRelativeReloc(const Relocation *pReloc) const {
Relocation *
AArch64LDBackend::findRelativeReloc(const Relocation *pReloc) const {
return m_RelativeRelocMap.lookup(pReloc);
}

Expand Down Expand Up @@ -894,7 +873,7 @@ ELFSection *AArch64LDBackend::mergeSection(ELFSection *S) {
// Read .note.gnu.property and extract features for pointer authentication.
template <class ELFT>
bool AArch64LDBackend::readGNUProperty(InputFile &pInput, ELFSection *S,
uint32_t &featureSet) {
uint32_t &featureSet) {
using Elf_Nhdr = typename ELFT::Nhdr;
using Elf_Note = typename ELFT::Note;

Expand Down Expand Up @@ -973,10 +952,10 @@ namespace eld {
//===----------------------------------------------------------------------===//
GNULDBackend *createAArch64LDBackend(Module &pModule) {
if (pModule.getConfig().targets().triple().isOSLinux())
return make<AArch64LDBackend>(
pModule, make<AArch64LinuxInfo>(pModule.getConfig()));
return make<AArch64LDBackend>(pModule,
make<AArch64LinuxInfo>(pModule.getConfig()));
return make<AArch64LDBackend>(pModule,
make<AArch64Info>(pModule.getConfig()));
make<AArch64Info>(pModule.getConfig()));
}

uint64_t AArch64LDBackend::StaticTCBSize = 0x10;
Expand Down
31 changes: 7 additions & 24 deletions lib/Target/ARM/ARMLDBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,31 +126,15 @@ void ARMGNULDBackend::initTargetSections(ObjectBuilder &pBuilder) {
}

void ARMGNULDBackend::initTargetSymbols() {
// Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
// same name in input
auto SymbolName = "_GLOBAL_OFFSET_TABLE_";
if (LinkerConfig::Object != config().codeGenType()) {
m_pGOTSymbol =
m_Module.getIRBuilder()
->addSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
m_Module.getInternalInput(Module::Script), SymbolName,
ResolveInfo::Object, ResolveInfo::Define, ResolveInfo::Local,
0x0, // size
0x0, // value
FragmentRef::null(), ResolveInfo::Hidden);
if (m_Module.getConfig().options().isSymbolTracingRequested() &&
m_Module.getConfig().options().traceSymbol(SymbolName))
config().raise(Diag::target_specific_symbol) << SymbolName;
if (m_pGOTSymbol)
m_pGOTSymbol->setShouldIgnore(false);
}
if (LinkerConfig::Object != config().codeGenType())
m_pGOTSymbol = defineGlobalOffsetTableSymbol();

// If linker script, lets not add this symbol.
if (m_Module.getScript().linkerScriptHasSectionsCommand())
return;

const NamePool& NP = m_Module.getNamePool();
SymbolName = "__exidx_start";
const NamePool &NP = m_Module.getNamePool();
const char *SymbolName = "__exidx_start";
const ResolveInfo *EXIDXStartInfo = NP.findInfo(SymbolName);
if (EXIDXStartInfo && EXIDXStartInfo->isUndef()) {
m_pEXIDXStart =
Expand Down Expand Up @@ -218,8 +202,7 @@ void ARMGNULDBackend::doPreLayout() {
if (isMicroController() &&
((config().codeGenType() == LinkerConfig::DynObj) ||
(config().options().isPIE()))) {
config().raise(Diag::not_supported) << "SharedLibrary/PIE"
<< "Cortex-M";
config().raise(Diag::not_supported) << "SharedLibrary/PIE" << "Cortex-M";
m_Module.setFailure(true);
return;
}
Expand Down Expand Up @@ -517,7 +500,7 @@ bool ARMGNULDBackend::readSection(InputFile &pInput, ELFSection *S) {
LayoutInfo *layoutInfo = getModule().getLayoutInfo();
if (layoutInfo)
layoutInfo->recordFragment(m_pARMAttributeSection->getInputFile(),
m_pARMAttributeSection, AttributeFragment);
m_pARMAttributeSection, AttributeFragment);
}
AttributeFragment->updateAttributes(
Region, m_Module, llvm::dyn_cast<ObjectFile>(&pInput), config());
Expand Down Expand Up @@ -1192,7 +1175,7 @@ void ARMGNULDBackend::finishAssignOutputSections() {
LayoutInfo *layoutInfo = getModule().getLayoutInfo();
if (layoutInfo)
layoutInfo->recordFragment(m_pRegionTableSection->getInputFile(),
m_pRegionTableSection, m_pRegionTableFragment);
m_pRegionTableSection, m_pRegionTableFragment);
}

// Update the RegionTable with updated information from the Backend.
Expand Down
16 changes: 16 additions & 0 deletions lib/Target/GNULDBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4885,6 +4885,22 @@ size_t GNULDBackend::getGOTSymbolAddr() const {
return (fragRef->getOutputOffset(m_Module) + section->addr());
}

LDSymbol *GNULDBackend::defineGlobalOffsetTableSymbol() {
const std::string SymbolName = "_GLOBAL_OFFSET_TABLE_";
LDSymbol *Sym =
m_Module.getIRBuilder()
->addSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
m_Module.getInternalInput(Module::Script), SymbolName,
ResolveInfo::Object, ResolveInfo::Define, ResolveInfo::Local, 0x0,
0x0, FragmentRef::null(), ResolveInfo::Hidden);
if (Sym)
Sym->setShouldIgnore(false);
if (m_Module.getConfig().options().isSymbolTracingRequested() &&
m_Module.getConfig().options().traceSymbol(SymbolName))
config().raise(Diag::target_specific_symbol) << SymbolName;
return Sym;
}

std::string
GNULDBackend::getCommonSymbolName(const CommonELFSection *commonSection) const {
llvm::StringRef sectionName = commonSection->name();
Expand Down
24 changes: 5 additions & 19 deletions lib/Target/Hexagon/HexagonLDBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ void HexagonLDBackend::createAttributeSection() {
AttributeFragment = make<HexagonAttributeFragment>(AttributeSection);
AttributeSection->addFragment(AttributeFragment);
if (auto *layoutInfo = getModule().getLayoutInfo())
layoutInfo->recordFragment(AttributeSection->getInputFile(), AttributeSection,
AttributeFragment);
layoutInfo->recordFragment(AttributeSection->getInputFile(),
AttributeSection, AttributeFragment);
}

void HexagonLDBackend::initTargetSections(ObjectBuilder &pBuilder) {
Expand Down Expand Up @@ -314,23 +314,9 @@ void HexagonLDBackend::initTargetSections(ObjectBuilder &pBuilder) {
void HexagonLDBackend::initTargetSymbols() {
if (config().codeGenType() == LinkerConfig::Object)
return;
auto SymbolName = "_GLOBAL_OFFSET_TABLE_";
// Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
// same name in input
m_pGOTSymbol =
m_Module.getIRBuilder()
->addSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
m_Module.getInternalInput(Module::Script), SymbolName,
ResolveInfo::Object, ResolveInfo::Define, ResolveInfo::Local,
0x0, // size
0x0, // value
FragmentRef::null(), ResolveInfo::Hidden);
if (m_pGOTSymbol)
m_pGOTSymbol->setShouldIgnore(false);
if (m_Module.getConfig().options().isSymbolTracingRequested() &&
m_Module.getConfig().options().traceSymbol(SymbolName))
config().raise(Diag::target_specific_symbol) << SymbolName;
SymbolName = "___end";
m_pGOTSymbol = defineGlobalOffsetTableSymbol();

const char *SymbolName = "___end";
m_pEndOfImage = m_Module.getNamePool().findSymbol(SymbolName);
if (!m_pEndOfImage)
m_pEndOfImage =
Expand Down
36 changes: 21 additions & 15 deletions lib/Target/RISCV/RISCVLDBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ void RISCVLDBackend::initTargetSections(ObjectBuilder &pBuilder) {
LayoutInfo *layoutInfo = getModule().getLayoutInfo();
if (layoutInfo)
layoutInfo->recordFragment(m_pRISCVAttributeSection->getInputFile(),
m_pRISCVAttributeSection, AttributeFragment);
m_pRISCVAttributeSection, AttributeFragment);
if (LinkerConfig::Object == config().codeGenType())
return;

Expand All @@ -135,7 +135,8 @@ void RISCVLDBackend::initPatchSections(ELFObjectFile &InputFile) {
void RISCVLDBackend::initTargetSymbols() {
if (config().codeGenType() == LinkerConfig::Object)
return;
// Do not create another __global_pointer$ when linking a patch.
m_pGOTSymbol = defineGlobalOffsetTableSymbol();

if (config().options().getPatchBase())
return;
if (m_Module.getScript().linkerScriptHasSectionsCommand()) {
Expand Down Expand Up @@ -312,7 +313,8 @@ bool RISCVLDBackend::doRelaxationCall(Relocation *reloc) {
->getInput()
->decoratedPath();

region->replaceInstruction(offset, reloc, reinterpret_cast<uint8_t *>(&c_j), 2);
region->replaceInstruction(offset, reloc, reinterpret_cast<uint8_t *>(&c_j),
2);
reloc->setTargetData(c_j);
reloc->setType(llvm::ELF::R_RISCV_RVC_JUMP);
relaxDeleteBytes("RISCV_CALL_C", *region, offset + 2, 6,
Expand All @@ -325,7 +327,8 @@ bool RISCVLDBackend::doRelaxationCall(Relocation *reloc) {
// Replace the instruction to JAL
uint32_t jal = 0x6fu | rd << 7;

region->replaceInstruction(offset, reloc, reinterpret_cast<uint8_t *>(&jal), 4);
region->replaceInstruction(offset, reloc, reinterpret_cast<uint8_t *>(&jal),
4);
reloc->setTargetData(jal);
reloc->setType(llvm::ELF::R_RISCV_JAL);
// Delete the next instruction
Expand All @@ -344,7 +347,8 @@ bool RISCVLDBackend::doRelaxationCall(Relocation *reloc) {
const char *msg =
(rd == 1) ? "R_RISCV_CALL_QC_E_JAL" : "R_RISCV_CALL_QC_E_J";

region->replaceInstruction(offset, reloc, reinterpret_cast<uint8_t *>(&qc_e_j), 6);
region->replaceInstruction(offset, reloc,
reinterpret_cast<uint8_t *>(&qc_e_j), 6);
reloc->setTargetData(qc_e_j);
reloc->setType(ELF::riscv::internal::R_RISCV_QC_E_CALL_PLT);
relaxDeleteBytes(msg, *region, offset + 6, 2, reloc->symInfo()->name());
Expand Down Expand Up @@ -405,26 +409,26 @@ bool RISCVLDBackend::doRelaxationQCCall(Relocation *reloc) {
->getInput()
->decoratedPath();

region->replaceInstruction(offset, reloc, reinterpret_cast<uint8_t *>(&compressed), 2);
region->replaceInstruction(offset, reloc,
reinterpret_cast<uint8_t *>(&compressed), 2);
// Replace the reloc to R_RISCV_RVC_JUMP
reloc->setType(llvm::ELF::R_RISCV_RVC_JUMP);
reloc->setTargetData(compressed);
relaxDeleteBytes(msg, *region, offset + 2, 4,
reloc->symInfo()->name());
relaxDeleteBytes(msg, *region, offset + 2, 4, reloc->symInfo()->name());
return true;
}

// Replace the instruction to JAL
unsigned rd = isTailCall ? /*x0*/ 0 : /*ra*/ 1;
uint32_t jal_instr = 0x6fu | rd << 7;
region->replaceInstruction(offset, reloc, reinterpret_cast<uint8_t *>(&jal_instr), 4);
region->replaceInstruction(offset, reloc,
reinterpret_cast<uint8_t *>(&jal_instr), 4);
// Replace the reloc to R_RISCV_JAL
reloc->setType(llvm::ELF::R_RISCV_JAL);
reloc->setTargetData(jal_instr);
// Delete the next instruction
const char *msg = isTailCall ? "RISCV_QC_E_J" : "RISCV_QC_E_JAL";
relaxDeleteBytes(msg, *region, offset + 4, 2,
reloc->symInfo()->name());
relaxDeleteBytes(msg, *region, offset + 4, 2, reloc->symInfo()->name());

return true;
}
Expand Down Expand Up @@ -621,7 +625,8 @@ bool RISCVLDBackend::doRelaxationQCELi(Relocation *reloc, Relocator::DWord G) {
if (canRelaxQcLi) {
uint32_t qc_li = 0x0000001bu | rd << 7;

region->replaceInstruction(offset, reloc, reinterpret_cast<uint8_t *>(&qc_li), 4);
region->replaceInstruction(offset, reloc,
reinterpret_cast<uint8_t *>(&qc_li), 4);
reloc->setTargetData(qc_li);
reloc->setType(ELF::riscv::internal::R_RISCV_QC_ABS20_U);
relaxDeleteBytes(msg, *region, offset + 4, 2, reloc->symInfo()->name());
Expand All @@ -633,7 +638,8 @@ bool RISCVLDBackend::doRelaxationQCELi(Relocation *reloc, Relocator::DWord G) {
unsigned rs = 3; // x3 = gp
uint32_t addi = 0x00000013u | (rd << 7) | (rs << 15);

region->replaceInstruction(offset, reloc, reinterpret_cast<uint8_t *>(&addi), 4);
region->replaceInstruction(offset, reloc,
reinterpret_cast<uint8_t *>(&addi), 4);
reloc->setTargetData(addi);
reloc->setType(ELF::riscv::internal::R_RISCV_GPREL_I);
relaxDeleteBytes(msg, *region, offset + 4, 2, reloc->symInfo()->name());
Expand Down Expand Up @@ -669,8 +675,8 @@ bool RISCVLDBackend::doRelaxationTLSDESC(Relocation &R, bool Relax) {
// Otherwise, the instruction is replaced with a NOP.
reportMissedRelaxation(RelaxType, *region, offset, 4, Sym.name());
uint32_t NOPi32 = static_cast<uint32_t>(NOP);
region->replaceInstruction(
offset, &R, reinterpret_cast<uint8_t *>(&NOPi32), 4);
region->replaceInstruction(offset, &R,
reinterpret_cast<uint8_t *>(&NOPi32), 4);
}
R.setType(llvm::ELF::R_RISCV_NONE);
return Relaxed;
Expand Down
Loading