Skip to content

Commit

Permalink
[LLD][COFF] Add support for CHPE code ranges metadata. (#105741)
Browse files Browse the repository at this point in the history
This is part of CHPE metadata containing a sorted list of x86_64 export
thunks RVAs and sizes.
  • Loading branch information
cjacek authored Aug 23, 2024
1 parent a0fac6f commit 52a7116
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 5 deletions.
16 changes: 16 additions & 0 deletions lld/COFF/Chunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,22 @@ void ECExportThunkChunk::writeTo(uint8_t *buf) const {
write32le(buf + 10, target->getRVA() - rva - 14);
}

size_t CHPECodeRangesChunk::getSize() const {
return exportThunks.size() * sizeof(chpe_code_range_entry);
}

void CHPECodeRangesChunk::writeTo(uint8_t *buf) const {
auto ranges = reinterpret_cast<chpe_code_range_entry *>(buf);

for (uint32_t i = 0; i < exportThunks.size(); i++) {
Chunk *thunk = exportThunks[i].first;
uint32_t start = thunk->getRVA();
ranges[i].StartRva = start;
ranges[i].EndRva = start + thunk->getSize();
ranges[i].EntryPoint = start;
}
}

size_t CHPERedirectionChunk::getSize() const {
return exportThunks.size() * sizeof(chpe_redirection_entry);
}
Expand Down
11 changes: 11 additions & 0 deletions lld/COFF/Chunks.h
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,17 @@ class ECCodeMapChunk : public NonSectionChunk {
std::vector<ECCodeMapEntry> &map;
};

class CHPECodeRangesChunk : public NonSectionChunk {
public:
CHPECodeRangesChunk(std::vector<std::pair<Chunk *, Defined *>> &exportThunks)
: exportThunks(exportThunks) {}
size_t getSize() const override;
void writeTo(uint8_t *buf) const override;

private:
std::vector<std::pair<Chunk *, Defined *>> &exportThunks;
};

class CHPERedirectionChunk : public NonSectionChunk {
public:
CHPERedirectionChunk(std::vector<std::pair<Chunk *, Defined *>> &exportThunks)
Expand Down
2 changes: 2 additions & 0 deletions lld/COFF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2444,6 +2444,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
ctx.symtab.addAbsolute("__arm64x_redirection_metadata_count", 0);
ctx.symtab.addAbsolute("__hybrid_code_map", 0);
ctx.symtab.addAbsolute("__hybrid_code_map_count", 0);
ctx.symtab.addAbsolute("__x64_code_ranges_to_entry_points", 0);
ctx.symtab.addAbsolute("__x64_code_ranges_to_entry_points_count", 0);
}

if (config->pseudoRelocs) {
Expand Down
10 changes: 10 additions & 0 deletions lld/COFF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2071,6 +2071,12 @@ void Writer::createECChunks() {
replaceSymbol<DefinedSynthetic>(codeMapSym, codeMapSym->getName(),
codeMapChunk);

CHPECodeRangesChunk *ranges = make<CHPECodeRangesChunk>(exportThunks);
rdataSec->addChunk(ranges);
Symbol *rangesSym =
ctx.symtab.findUnderscore("__x64_code_ranges_to_entry_points");
replaceSymbol<DefinedSynthetic>(rangesSym, rangesSym->getName(), ranges);

CHPERedirectionChunk *entryPoints = make<CHPERedirectionChunk>(exportThunks);
a64xrmSec->addChunk(entryPoints);
Symbol *entryPointsSym =
Expand Down Expand Up @@ -2186,6 +2192,10 @@ void Writer::setECSymbols() {
pdata.first->getRVA());
}

Symbol *rangesCountSym =
ctx.symtab.findUnderscore("__x64_code_ranges_to_entry_points_count");
cast<DefinedAbsolute>(rangesCountSym)->setVA(exportThunks.size());

Symbol *entryPointCountSym =
ctx.symtab.findUnderscore("__arm64x_redirection_metadata_count");
cast<DefinedAbsolute>(entryPointCountSym)->setVA(exportThunks.size());
Expand Down
4 changes: 2 additions & 2 deletions lld/test/COFF/Inputs/loadconfig-arm64ec.s
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ __chpe_metadata:
.word 1
.rva __hybrid_code_map
.word __hybrid_code_map_count
.word 0 // __x64_code_ranges_to_entry_points
.rva __x64_code_ranges_to_entry_points
.rva __arm64x_redirection_metadata
.rva __os_arm64x_dispatch_call_no_redirect
.rva __os_arm64x_dispatch_ret
Expand All @@ -75,7 +75,7 @@ __chpe_metadata:
.rva __os_arm64x_check_icall_cfg
.word 0 // __arm64x_native_entrypoint
.word 0 // __hybrid_auxiliary_iat
.word 0 // __x64_code_ranges_to_entry_points_count
.word __x64_code_ranges_to_entry_points_count
.word __arm64x_redirection_metadata_count
.rva __os_arm64x_get_x64_information
.rva __os_arm64x_set_x64_information
Expand Down
9 changes: 7 additions & 2 deletions lld/test/COFF/arm64ec-export-thunks.test
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ EXP-CHPE: CodeMap [
EXP-CHPE-NEXT: 0x1000 - 0x100C ARM64EC
EXP-CHPE-NEXT: 0x2000 - 0x3020 X64
EXP-CHPE-NEXT: ]
EXP-CHPE-NEXT: CodeRangesToEntryPoints: 0
EXP-CHPE-NEXT: CodeRangesToEntryPoints [
EXP-CHPE-NEXT: 0x3000 - 0x3010 -> 0x3000
EXP-CHPE-NEXT: 0x3010 - 0x3020 -> 0x3010
EXP-CHPE-NEXT: ]
EXP-CHPE-NEXT: RedirectionMetadata [
EXP-CHPE-NEXT: 0x3000 -> 0x1000
EXP-CHPE-NEXT: 0x3010 -> 0x1000
Expand Down Expand Up @@ -121,7 +124,9 @@ ENTRY-CHPE: CodeMap [
ENTRY-CHPE-NEXT: 0x1000 - 0x100C ARM64EC
ENTRY-CHPE-NEXT: 0x2000 - 0x2010 X64
ENTRY-CHPE-NEXT: ]
ENTRY-CHPE-NEXT: CodeRangesToEntryPoints: 0
ENTRY-CHPE-NEXT: CodeRangesToEntryPoints [
ENTRY-CHPE-NEXT: 0x2000 - 0x2010 -> 0x2000
ENTRY-CHPE-NEXT: ]
ENTRY-CHPE-NEXT: RedirectionMetadata [
ENTRY-CHPE-NEXT: 0x2000 -> 0x1000
ENTRY-CHPE-NEXT: ]
Expand Down
4 changes: 3 additions & 1 deletion lld/test/COFF/arm64ec-patchable-thunks.test
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ PATCH-CHPE: CodeMap [
PATCH-CHPE-NEXT: 0x1000 - 0x1008 ARM64EC
PATCH-CHPE-NEXT: 0x2000 - 0x2010 X64
PATCH-CHPE-NEXT: ]
PATCH-CHPE-NEXT: CodeRangesToEntryPoints: 0
PATCH-CHPE-NEXT: CodeRangesToEntryPoints [
PATCH-CHPE-NEXT: 0x2000 - 0x2010 -> 0x2000
PATCH-CHPE-NEXT: ]
PATCH-CHPE-NEXT: RedirectionMetadata [
PATCH-CHPE-NEXT: 0x2000 -> 0x1000
PATCH-CHPE-NEXT: ]
Expand Down

0 comments on commit 52a7116

Please sign in to comment.