Skip to content

[LLD][COFF] Always locate the IAT at the beginning of the .rdata section and align its size to 4KB on ARM64EC. #107588

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 8, 2024
Merged
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
29 changes: 29 additions & 0 deletions lld/COFF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ class Writer {
void createExportTable();
void mergeSections();
void sortECChunks();
void appendECImportTables();
void removeUnusedSections();
void assignAddresses();
bool isInRange(uint16_t relType, uint64_t s, uint64_t p, int margin,
Expand Down Expand Up @@ -753,6 +754,7 @@ void Writer::run() {
createExportTable();
mergeSections();
sortECChunks();
appendECImportTables();
removeUnusedSections();
finalizeAddresses();
removeEmptySections();
Expand Down Expand Up @@ -914,6 +916,28 @@ void Writer::addSyntheticIdata() {
add(".idata$7", idata.dllNames);
}

void Writer::appendECImportTables() {
if (!isArm64EC(ctx.config.machine))
return;

const uint32_t rdata = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;

// IAT is always placed at the begining of .rdata section and its size
// is aligned to 4KB. Insert it here, after all merges all done.
if (PartialSection *importAddresses = findPartialSection(".idata$5", rdata)) {
if (!rdataSec->chunks.empty())
rdataSec->chunks.front()->setAlignment(
std::max(0x1000u, rdataSec->chunks.front()->getAlignment()));
iatSize = alignTo(iatSize, 0x1000);

rdataSec->chunks.insert(rdataSec->chunks.begin(),
importAddresses->chunks.begin(),
importAddresses->chunks.end());
rdataSec->contribSections.insert(rdataSec->contribSections.begin(),
importAddresses);
}
}

// Locate the first Chunk and size of the import directory list and the
// IAT.
void Writer::locateImportTables() {
Expand Down Expand Up @@ -1069,6 +1093,11 @@ void Writer::createSections() {
sortCRTSectionChunks(pSec->chunks);
}

// ARM64EC has specific placement and alignment requirements for the IAT.
// Delay adding its chunks until appendECImportTables.
if (isArm64EC(ctx.config.machine) && pSec->name == ".idata$5")
continue;

OutputSection *sec = createSection(name, outChars);
for (Chunk *c : pSec->chunks)
sec->addChunk(c);
Expand Down
15 changes: 10 additions & 5 deletions lld/test/COFF/arm64ec-import.test
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,33 @@ RUN: llvm-readobj --coff-imports out2.dll | FileCheck --check-prefix=IMPORTS %s
IMPORTS: Import {
IMPORTS-NEXT: Name: test.dll
IMPORTS-NEXT: ImportLookupTableRVA:
IMPORTS-NEXT: ImportAddressTableRVA: 0x2258
IMPORTS-NEXT: ImportAddressTableRVA: 0x2000
IMPORTS-NEXT: Symbol: data (0)
IMPORTS-NEXT: Symbol: func (0)
IMPORTS-NEXT: Symbol: func2 (0)
IMPORTS-NEXT: }
IMPORTS-NEXT: Import {
IMPORTS-NEXT: Name: test2.dll
IMPORTS-NEXT: ImportLookupTableRVA:
IMPORTS-NEXT: ImportAddressTableRVA: 0x2278
IMPORTS-NEXT: ImportAddressTableRVA: 0x2020
IMPORTS-NEXT: Symbol: t2func (0)
IMPORTS-NEXT: }

RUN: llvm-objdump -d out.dll | FileCheck --check-prefix=DISASM %s
RUN: llvm-objdump -d out2.dll | FileCheck --check-prefix=DISASM %s

DISASM: 0000000180001000 <.text>:
DISASM-NEXT: 180001000: ff 25 5a 12 00 00 jmpq *0x125a(%rip) # 0x180002260
DISASM-NEXT: 180001000: ff 25 02 10 00 00 jmpq *0x1002(%rip) # 0x180002008

RUN: llvm-readobj --hex-dump=.test out.dll | FileCheck --check-prefix=TESTSEC %s
RUN: llvm-readobj --hex-dump=.test out2.dll | FileCheck --check-prefix=TESTSEC %s
TESTSEC: 0x180004000 60220000 58220000 68220000 78220000
TESTSEC-NEXT: 0x180004010 00100000
TESTSEC: 0x180005000 08200000 00200000 10200000 20200000
TESTSEC-NEXT: 0x180005010 00100000

RUN: llvm-readobj --headers out.dll | FileCheck -check-prefix=HEADERS %s
HEADERS: LoadConfigTableRVA: 0x3008
HEADERS: IATRVA: 0x2000
HEADERS: IATSize: 0x1000

#--- test.s
.section .test, "r"
Expand Down
Loading