Skip to content

Commit

Permalink
[lld][COFF][NFC] Factor out exception table sorting. (llvm#72518)
Browse files Browse the repository at this point in the history
This is a preparation for ARM64EC support, which needs to sort both ARM
and x86_64 tables separately.
  • Loading branch information
cjacek authored Nov 17, 2023
1 parent a67b85e commit ec42d54
Showing 1 changed file with 41 additions and 29 deletions.
70 changes: 41 additions & 29 deletions lld/COFF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,8 @@ class Writer {
void writeBuildId();
void writePEChecksum();
void sortSections();
void sortExceptionTable();
template <typename T> void sortExceptionTable(Chunk *first, Chunk *last);
void sortExceptionTables();
void sortCRTSectionChunks(std::vector<Chunk *> &chunks);
void addSyntheticIdata();
void sortBySectionOrder(std::vector<Chunk *> &chunks);
Expand Down Expand Up @@ -751,7 +752,7 @@ void Writer::run() {
}
writeSections();
prepareLoadConfig();
sortExceptionTable();
sortExceptionTables();

// Fix up the alignment in the TLS Directory's characteristic field,
// if a specific alignment value is needed
Expand Down Expand Up @@ -2164,41 +2165,52 @@ void Writer::writeBuildId() {
}

// Sort .pdata section contents according to PE/COFF spec 5.5.
void Writer::sortExceptionTable() {
if (!firstPdata)
return;
llvm::TimeTraceScope timeScope("Sort exception table");
template <typename T>
void Writer::sortExceptionTable(Chunk *first, Chunk *last) {
// We assume .pdata contains function table entries only.
auto bufAddr = [&](Chunk *c) {
OutputSection *os = ctx.getOutputSection(c);
return buffer->getBufferStart() + os->getFileOff() + c->getRVA() -
os->getRVA();
};
uint8_t *begin = bufAddr(firstPdata);
uint8_t *end = bufAddr(lastPdata) + lastPdata->getSize();
if (ctx.config.machine == AMD64) {
struct Entry { ulittle32_t begin, end, unwind; };
if ((end - begin) % sizeof(Entry) != 0) {
fatal("unexpected .pdata size: " + Twine(end - begin) +
" is not a multiple of " + Twine(sizeof(Entry)));
}
parallelSort(
MutableArrayRef<Entry>((Entry *)begin, (Entry *)end),
[](const Entry &a, const Entry &b) { return a.begin < b.begin; });
return;
uint8_t *begin = bufAddr(first);
uint8_t *end = bufAddr(last) + last->getSize();
if ((end - begin) % sizeof(T) != 0) {
fatal("unexpected .pdata size: " + Twine(end - begin) +
" is not a multiple of " + Twine(sizeof(T)));
}
if (ctx.config.machine == ARMNT || ctx.config.machine == ARM64) {
struct Entry { ulittle32_t begin, unwind; };
if ((end - begin) % sizeof(Entry) != 0) {
fatal("unexpected .pdata size: " + Twine(end - begin) +
" is not a multiple of " + Twine(sizeof(Entry)));
}
parallelSort(
MutableArrayRef<Entry>((Entry *)begin, (Entry *)end),
[](const Entry &a, const Entry &b) { return a.begin < b.begin; });
return;

parallelSort(MutableArrayRef<T>(reinterpret_cast<T *>(begin),
reinterpret_cast<T *>(end)),
[](const T &a, const T &b) { return a.begin < b.begin; });
}

// Sort .pdata section contents according to PE/COFF spec 5.5.
void Writer::sortExceptionTables() {
llvm::TimeTraceScope timeScope("Sort exception table");

struct EntryX64 {
ulittle32_t begin, end, unwind;
};
struct EntryArm {
ulittle32_t begin, unwind;
};

switch (ctx.config.machine) {
case AMD64:
if (firstPdata)
sortExceptionTable<EntryX64>(firstPdata, lastPdata);
break;
case ARMNT:
case ARM64:
if (firstPdata)
sortExceptionTable<EntryArm>(firstPdata, lastPdata);
break;
default:
if (firstPdata)
lld::errs() << "warning: don't know how to handle .pdata.\n";
break;
}
lld::errs() << "warning: don't know how to handle .pdata.\n";
}

// The CRT section contains, among other things, the array of function
Expand Down

0 comments on commit ec42d54

Please sign in to comment.