Skip to content

Commit

Permalink
[LLD][RISCV] Emit synthetic .riscv.lpadinfo section
Browse files Browse the repository at this point in the history
  • Loading branch information
mylai-mtk committed Jan 9, 2025
1 parent 109fb7c commit cde0a27
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lld/ELF/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1598,3 +1598,9 @@ void elf::setRISCVTargetInfo(Ctx &ctx) {
void elf::readRISCVLpadinfo(Ctx &ctx) {
static_cast<RISCV *>(ctx.target.get())->readLpadinfoSec();
}

uint32_t elf::getRISCVLpadValue(Ctx &ctx, const Symbol &sym,
const DiagLevel diagLvOnNotFound) {
return static_cast<RISCV *>(ctx.target.get())
->getLpadVal(sym, diagLvOnNotFound);
}
1 change: 1 addition & 0 deletions lld/ELF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ struct InStruct {
std::unique_ptr<StringTableSection> strTab;
std::unique_ptr<SymbolTableBaseSection> symTab;
std::unique_ptr<SymtabShndxSection> symTabShndx;
std::unique_ptr<SyntheticSection> riscvLpadinfo;
};

struct Ctx : CommonLinkerContext {
Expand Down
116 changes: 116 additions & 0 deletions lld/ELF/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4647,6 +4647,107 @@ size_t MemtagGlobalDescriptors::getSize() const {
return createMemtagGlobalDescriptors(ctx, symbols);
}

RISCVLpadinfoSection::RISCVLpadinfoSection(
Ctx &ctx, const SymbolTableBaseSection &symTab) :
SyntheticSection(ctx, ".riscv.lpadinfo", SHT_RISCV_LPADINFO, 0, 1),
symTab(symTab) {
switch (ctx.arg.ekind) {
case lld::elf::ELF32LEKind:
entsize = sizeof(Elf_Riscv_LpadInfo<llvm::object::ELF32LE>);
break;
case lld::elf::ELF32BEKind:
entsize = sizeof(Elf_Riscv_LpadInfo<llvm::object::ELF32BE>);
break;
case lld::elf::ELF64LEKind:
entsize = sizeof(Elf_Riscv_LpadInfo<llvm::object::ELF64LE>);
break;
case lld::elf::ELF64BEKind:
entsize = sizeof(Elf_Riscv_LpadInfo<llvm::object::ELF64BE>);
break;
default:
llvm_unreachable("unknown ctx.arg.ekind");
}
}

bool RISCVLpadinfoSection::isSymTabFinalized() const {
if (const OutputSection *const osec = symTab.getParent())
return osec->info;
// if symTab is not in output, it's dropped and considered "finalized"
return true;
}

bool RISCVLpadinfoSection::isNeedLpadinfoEntry(const Symbol &sym) {
return !sym.isUndefined() && sym.isFunc() && (sym.isGlobal() || sym.isWeak());
}

size_t RISCVLpadinfoSection::getSize() const {
size_t numLocals;
if (const OutputSection *const osec = symTab.getParent();
osec && isSymTabFinalized())
numLocals = osec->info - 1;
else
numLocals = 0;

size_t size = 0;
for (const SymbolTableEntry &ste : symTab.getSymbols().slice(numLocals)) {
if (isNeedLpadinfoEntry(*ste.sym))
size += entsize;
}
return size;
}

bool RISCVLpadinfoSection::isNeeded() const {
if (!(ctx.arg.andFeatures & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG))
return false;
if (!(symTab.getParent() && symTab.isNeeded()))
return false;
if (!isSymTabFinalized())
return true;

if (const OutputSection *const osec = symTab.getParent()) {
const size_t numLocals = osec->info - 1;
for (const SymbolTableEntry &ste : symTab.getSymbols().slice(numLocals))
if (isNeedLpadinfoEntry(*ste.sym))
return true;
}
return false;
}

void RISCVLpadinfoSection::finalizeContents() {
assert(isSymTabFinalized() &&
".riscv.lpadinfo section should be finalized after symbol tables are "
"finalized");
size = getSize();

const OutputSection *const symTabOsec = symTab.getParent();
assert(symTabOsec && "Corresponding symbol table should not be dropped");
link = symTabOsec->sectionIndex;
}

template <class ELFT>
void RISCVLpadinfoSection::writeLpadinfoEntry(
uint8_t *const buf, const size_t symIdx, const uint32_t lpadVal) {
auto *const eLpi = reinterpret_cast<Elf_Riscv_LpadInfo<ELFT> *>(buf);
eLpi->lpi_sym = symIdx;
eLpi->lpi_value = lpadVal;
}

void RISCVLpadinfoSection::writeTo(uint8_t *buf) {
const OutputSection *const symTabOsec = symTab.getParent();
assert(symTabOsec && "Corresponding symbol table should not be dropped");
const size_t firstGlobal = symTabOsec->info;
const ArrayRef<SymbolTableEntry> syms = symTab.getSymbols();
for (size_t i = firstGlobal, end = symTab.getNumSymbols(); i != end; ++i) {
const Symbol &sym = *syms[i - 1].sym;
if (!isNeedLpadinfoEntry(sym))
continue;

const uint32_t lpadVal = getRISCVLpadValue(ctx, sym);
invokeELFT(writeLpadinfoEntry, buf, i, lpadVal);
buf += entsize;
}
}

static OutputSection *findSection(Ctx &ctx, StringRef name) {
for (SectionCommand *cmd : ctx.script->sectionCommands)
if (auto *osd = dyn_cast<OutputDesc>(cmd))
Expand Down Expand Up @@ -4800,6 +4901,13 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {

add(*part.dynamic);
add(*part.dynStrTab);

if (ctx.arg.emachine == EM_RISCV &&
((ctx.arg.andFeatures & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG))) {
part.riscvLpadinfo =
std::make_unique<RISCVLpadinfoSection>(ctx, *part.dynSymTab);
add(*part.riscvLpadinfo);
}
}
add(*part.relaDyn);

Expand Down Expand Up @@ -4948,6 +5056,14 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
add(*ctx.in.shStrTab);
if (ctx.in.strTab)
add(*ctx.in.strTab);

if (ctx.arg.emachine == EM_RISCV &&
(ctx.arg.andFeatures & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG) &&
ctx.in.symTab && !ctx.arg.hasDynSymTab) {
ctx.in.riscvLpadinfo =
std::make_unique<RISCVLpadinfoSection>(ctx, *ctx.in.symTab);
add(*ctx.in.riscvLpadinfo);
}
}

template void elf::splitSections<ELF32LE>(Ctx &);
Expand Down
21 changes: 21 additions & 0 deletions lld/ELF/SyntheticSections.h
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,26 @@ class PPC64LongBranchTargetSection final : public SyntheticSection {
bool finalized = false;
};

class RISCVLpadinfoSection final : public SyntheticSection {
public:
RISCVLpadinfoSection(Ctx &ctx, const SymbolTableBaseSection &symTab);

size_t getSize() const override;
bool isNeeded() const override;
void finalizeContents() override;
void writeTo(uint8_t *buf) override;

private:
bool isSymTabFinalized() const;
static bool isNeedLpadinfoEntry(const Symbol &sym);

template <class ELFT>
static void writeLpadinfoEntry(uint8_t *const buf, const size_t symIdx,
const uint32_t lpadVal);

const SymbolTableBaseSection &symTab;
};

template <typename ELFT>
class PartitionElfHeaderSection final : public SyntheticSection {
public:
Expand Down Expand Up @@ -1490,6 +1510,7 @@ struct Partition {
std::unique_ptr<SyntheticSection> programHeaders;
SmallVector<std::unique_ptr<PhdrEntry>, 0> phdrs;

std::unique_ptr<RISCVLpadinfoSection> riscvLpadinfo;
std::unique_ptr<ARMExidxSyntheticSection> armExidx;
std::unique_ptr<BuildIdSection> buildId;
std::unique_ptr<SyntheticSection> dynamic;
Expand Down
2 changes: 2 additions & 0 deletions lld/ELF/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type);
void riscvFinalizeRelax(int passes);
void mergeRISCVAttributesSections(Ctx &);
void readRISCVLpadinfo(Ctx &);
uint32_t getRISCVLpadValue(Ctx &, const Symbol &,
const DiagLevel diagLvOnNotFound = DiagLevel::Err);
void addArmInputSectionMappingSymbols(Ctx &);
void addArmSyntheticSectionMappingSymbol(Defined *);
void sortArmMappingSymbols(Ctx &);
Expand Down
2 changes: 2 additions & 0 deletions lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2043,6 +2043,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
finalizeSynthetic(ctx, part.verSym.get());
finalizeSynthetic(ctx, part.verNeed.get());
finalizeSynthetic(ctx, part.dynamic.get());
finalizeSynthetic(ctx, part.riscvLpadinfo.get());
}
}

Expand Down Expand Up @@ -2084,6 +2085,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
finalizeSynthetic(ctx, ctx.in.debugNames.get());
finalizeSynthetic(ctx, ctx.in.ppc64LongBranchTarget.get());
finalizeSynthetic(ctx, ctx.in.armCmseSGSection.get());
finalizeSynthetic(ctx, ctx.in.riscvLpadinfo.get());
}

// Relaxation to delete inter-basic block jumps created by basic block
Expand Down

0 comments on commit cde0a27

Please sign in to comment.