Skip to content

Commit f04aaf9

Browse files
committed
[ORC][ELF] Process .init_array sections in priority order.
Fixes compiler-rt/test/orc/TestCases/Linux/x86-64/priority-static-initializer.S testcase after 244ea40. This testcase had been succeeding because the definition order of the .init_array sections in the testcase matched their priorities, but began failing once 244ea40 removed that guarantee. The proper fix is to visit the .init_array sections according to their priority order, regardless of how they're defined in the file. This fixes the single-file testcase, but I think that ELFNixPlatform will need to be extended to make priorities work correctly across file boundaries.
1 parent 841227a commit f04aaf9

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -921,12 +921,42 @@ Error ELFNixPlatform::ELFNixPlatformPlugin::registerInitSections(
921921
SmallVector<ExecutorAddrRange> ELFNixPlatformSecs;
922922
LLVM_DEBUG(dbgs() << "ELFNixPlatform::registerInitSections\n");
923923

924-
for (auto &Sec : G.sections()) {
925-
if (isELFInitializerSection(Sec.getName())) {
926-
jitlink::SectionRange R(Sec);
927-
ELFNixPlatformSecs.push_back(R.getRange());
924+
SmallVector<jitlink::Section *> OrderedInitSections;
925+
for (auto &Sec : G.sections())
926+
if (isELFInitializerSection(Sec.getName()))
927+
OrderedInitSections.push_back(&Sec);
928+
929+
// FIXME: This handles priority order within the current graph, but we'll need
930+
// to include priority information in the initializer allocation
931+
// actions in order to respect the ordering across multiple graphs.
932+
llvm::sort(OrderedInitSections, [](const jitlink::Section *LHS,
933+
const jitlink::Section *RHS) {
934+
if (LHS->getName().starts_with(".init_array")) {
935+
if (RHS->getName().starts_with(".init_array")) {
936+
StringRef LHSPrioStr(LHS->getName());
937+
StringRef RHSPrioStr(RHS->getName());
938+
uint64_t LHSPriority;
939+
bool LHSHasPriority = LHSPrioStr.consume_front(".init_array.") &&
940+
!LHSPrioStr.getAsInteger(10, LHSPriority);
941+
uint64_t RHSPriority;
942+
bool RHSHasPriority = RHSPrioStr.consume_front(".init_array.") &&
943+
!RHSPrioStr.getAsInteger(10, RHSPriority);
944+
if (LHSHasPriority)
945+
return RHSHasPriority ? LHSPriority < RHSPriority : true;
946+
else if (RHSHasPriority)
947+
return false;
948+
// If we get here we'll fall through to the
949+
// LHS->getName() < RHS->getName() test below.
950+
} else {
951+
// .init_array[.N] comes before any non-.init_array[.N] section.
952+
return true;
953+
}
928954
}
929-
}
955+
return LHS->getName() < RHS->getName();
956+
});
957+
958+
for (auto &Sec : OrderedInitSections)
959+
ELFNixPlatformSecs.push_back(jitlink::SectionRange(*Sec).getRange());
930960

931961
// Dump the scraped inits.
932962
LLVM_DEBUG({

0 commit comments

Comments
 (0)