Skip to content

Commit c206caa

Browse files
committed
Merge from 'main' to 'sycl-web' (128 commits)
CONFLICT (content): Merge conflict in clang/lib/CodeGen/BackendUtil.cpp CONFLICT (content): Merge conflict in clang/lib/CodeGen/CodeGenAction.cpp
2 parents 22ca174 + c6cf329 commit c206caa

File tree

485 files changed

+17110
-4109
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

485 files changed

+17110
-4109
lines changed

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,15 @@ class BinaryContext {
680680
/// the execution of the binary is completed.
681681
std::optional<uint64_t> FiniFunctionAddress;
682682

683+
/// DT_FINI.
684+
std::optional<uint64_t> FiniAddress;
685+
686+
/// DT_FINI_ARRAY. Only used when DT_FINI is not set.
687+
std::optional<uint64_t> FiniArrayAddress;
688+
689+
/// DT_FINI_ARRAYSZ. Only used when DT_FINI is not set.
690+
std::optional<uint64_t> FiniArraySize;
691+
683692
/// Page alignment used for code layout.
684693
uint64_t PageAlign{HugePageSize};
685694

bolt/include/bolt/Core/BinarySection.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,12 @@ class BinarySection {
375375
/// Add a dynamic relocation at the given /p Offset.
376376
void addDynamicRelocation(uint64_t Offset, MCSymbol *Symbol, uint64_t Type,
377377
uint64_t Addend, uint64_t Value = 0) {
378-
assert(Offset < getSize() && "offset not within section bounds");
379-
DynamicRelocations.emplace(Relocation{Offset, Symbol, Type, Addend, Value});
378+
addDynamicRelocation(Relocation{Offset, Symbol, Type, Addend, Value});
379+
}
380+
381+
void addDynamicRelocation(const Relocation &Reloc) {
382+
assert(Reloc.Offset < getSize() && "offset not within section bounds");
383+
DynamicRelocations.emplace(Reloc);
380384
}
381385

382386
/// Add relocation against the original contents of this section.
@@ -410,6 +414,18 @@ class BinarySection {
410414
return Itr != DynamicRelocations.end() ? &*Itr : nullptr;
411415
}
412416

417+
std::optional<Relocation> takeDynamicRelocationAt(uint64_t Offset) {
418+
Relocation Key{Offset, 0, 0, 0, 0};
419+
auto Itr = DynamicRelocations.find(Key);
420+
421+
if (Itr == DynamicRelocations.end())
422+
return std::nullopt;
423+
424+
Relocation Reloc = *Itr;
425+
DynamicRelocations.erase(Itr);
426+
return Reloc;
427+
}
428+
413429
uint64_t hash(const BinaryData &BD) const {
414430
std::map<const BinaryData *, uint64_t> Cache;
415431
return hash(BD, Cache);

bolt/include/bolt/Core/Relocation.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ struct Relocation {
124124
/// otherwise.
125125
bool isRelative() const { return isRelative(Type); }
126126

127+
/// Return true if this relocation is R_*_IRELATIVE type. Return false
128+
/// otherwise.
129+
bool isIRelative() const { return isIRelative(Type); }
130+
127131
/// Emit relocation at a current \p Streamer' position. The caller is
128132
/// responsible for setting the position correctly.
129133
size_t emit(MCStreamer *Streamer) const;

bolt/include/bolt/Rewrite/RewriteInstance.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ class RewriteInstance {
9595
/// from meta data in the file.
9696
void discoverFileObjects();
9797

98+
/// Check whether we should use DT_FINI or DT_FINI_ARRAY for instrumentation.
99+
/// DT_FINI is preferred; DT_FINI_ARRAY is only used when no DT_FINI entry was
100+
/// found.
101+
Error discoverRtFiniAddress();
102+
103+
/// If DT_FINI_ARRAY is used for instrumentation, update the relocation of its
104+
/// first entry to point to the instrumentation library's fini address.
105+
void updateRtFiniReloc();
106+
98107
/// Create and initialize metadata rewriters for this instance.
99108
void initializeMetadataManager();
100109

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4176,7 +4176,7 @@ void BinaryFunction::updateOutputValues(const BOLTLinker &Linker) {
41764176
assert(PrevBB->getOutputAddressRange().first <= BBAddress &&
41774177
"Bad output address for basic block.");
41784178
assert((PrevBB->getOutputAddressRange().first != BBAddress ||
4179-
!hasInstructions() || PrevBB->empty()) &&
4179+
!hasInstructions() || !PrevBB->getNumNonPseudos()) &&
41804180
"Bad output address for basic block.");
41814181
PrevBB->setOutputEndAddress(BBAddress);
41824182
}

bolt/lib/Core/Relocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,9 @@ static uint64_t encodeValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) {
365365
switch (Type) {
366366
default:
367367
llvm_unreachable("unsupported relocation");
368+
case ELF::R_AARCH64_ABS16:
368369
case ELF::R_AARCH64_ABS32:
370+
case ELF::R_AARCH64_ABS64:
369371
break;
370372
case ELF::R_AARCH64_PREL16:
371373
case ELF::R_AARCH64_PREL32:

bolt/lib/Passes/PatchEntries.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ void PatchEntries::runOnFunctions(BinaryContext &BC) {
9898
});
9999

100100
if (!Success) {
101+
// We can't change output layout for AArch64 due to LongJmp pass
102+
if (BC.isAArch64()) {
103+
if (opts::ForcePatch) {
104+
errs() << "BOLT-ERROR: unable to patch entries in " << Function
105+
<< "\n";
106+
exit(1);
107+
}
108+
109+
continue;
110+
}
111+
101112
// If the original function entries cannot be patched, then we cannot
102113
// safely emit new function body.
103114
errs() << "BOLT-WARNING: failed to patch entries in " << Function

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 108 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,10 @@ Error RewriteInstance::run() {
704704
adjustCommandLineOptions();
705705
discoverFileObjects();
706706

707+
if (opts::Instrument && !BC->IsStaticExecutable)
708+
if (Error E = discoverRtFiniAddress())
709+
return E;
710+
707711
preprocessProfileData();
708712

709713
// Skip disassembling if we have a translation table and we are running an
@@ -740,6 +744,9 @@ Error RewriteInstance::run() {
740744

741745
updateMetadata();
742746

747+
if (opts::Instrument && !BC->IsStaticExecutable)
748+
updateRtFiniReloc();
749+
743750
if (opts::LinuxKernelMode) {
744751
errs() << "BOLT-WARNING: not writing the output file for Linux Kernel\n";
745752
return Error::success();
@@ -1280,6 +1287,77 @@ void RewriteInstance::discoverFileObjects() {
12801287
registerFragments();
12811288
}
12821289

1290+
Error RewriteInstance::discoverRtFiniAddress() {
1291+
// Use DT_FINI if it's available.
1292+
if (BC->FiniAddress) {
1293+
BC->FiniFunctionAddress = BC->FiniAddress;
1294+
return Error::success();
1295+
}
1296+
1297+
if (!BC->FiniArrayAddress || !BC->FiniArraySize) {
1298+
return createStringError(
1299+
std::errc::not_supported,
1300+
"Instrumentation needs either DT_FINI or DT_FINI_ARRAY");
1301+
}
1302+
1303+
if (*BC->FiniArraySize < BC->AsmInfo->getCodePointerSize()) {
1304+
return createStringError(std::errc::not_supported,
1305+
"Need at least 1 DT_FINI_ARRAY slot");
1306+
}
1307+
1308+
ErrorOr<BinarySection &> FiniArraySection =
1309+
BC->getSectionForAddress(*BC->FiniArrayAddress);
1310+
if (auto EC = FiniArraySection.getError())
1311+
return errorCodeToError(EC);
1312+
1313+
if (const Relocation *Reloc = FiniArraySection->getDynamicRelocationAt(0)) {
1314+
BC->FiniFunctionAddress = Reloc->Addend;
1315+
return Error::success();
1316+
}
1317+
1318+
if (const Relocation *Reloc = FiniArraySection->getRelocationAt(0)) {
1319+
BC->FiniFunctionAddress = Reloc->Value;
1320+
return Error::success();
1321+
}
1322+
1323+
return createStringError(std::errc::not_supported,
1324+
"No relocation for first DT_FINI_ARRAY slot");
1325+
}
1326+
1327+
void RewriteInstance::updateRtFiniReloc() {
1328+
// Updating DT_FINI is handled by patchELFDynamic.
1329+
if (BC->FiniAddress)
1330+
return;
1331+
1332+
const RuntimeLibrary *RT = BC->getRuntimeLibrary();
1333+
if (!RT || !RT->getRuntimeFiniAddress())
1334+
return;
1335+
1336+
assert(BC->FiniArrayAddress && BC->FiniArraySize &&
1337+
"inconsistent .fini_array state");
1338+
1339+
ErrorOr<BinarySection &> FiniArraySection =
1340+
BC->getSectionForAddress(*BC->FiniArrayAddress);
1341+
assert(FiniArraySection && ".fini_array removed");
1342+
1343+
if (std::optional<Relocation> Reloc =
1344+
FiniArraySection->takeDynamicRelocationAt(0)) {
1345+
assert(Reloc->Addend == BC->FiniFunctionAddress &&
1346+
"inconsistent .fini_array dynamic relocation");
1347+
Reloc->Addend = RT->getRuntimeFiniAddress();
1348+
FiniArraySection->addDynamicRelocation(*Reloc);
1349+
}
1350+
1351+
// Update the static relocation by adding a pending relocation which will get
1352+
// patched when flushPendingRelocations is called in rewriteFile. Note that
1353+
// flushPendingRelocations will calculate the value to patch as
1354+
// "Symbol + Addend". Since we don't have a symbol, just set the addend to the
1355+
// desired value.
1356+
FiniArraySection->addPendingRelocation(Relocation{
1357+
/*Offset*/ 0, /*Symbol*/ nullptr, /*Type*/ Relocation::getAbs64(),
1358+
/*Addend*/ RT->getRuntimeFiniAddress(), /*Value*/ 0});
1359+
}
1360+
12831361
void RewriteInstance::registerFragments() {
12841362
if (!BC->HasSplitFunctions)
12851363
return;
@@ -1344,24 +1422,41 @@ void RewriteInstance::createPLTBinaryFunction(uint64_t TargetAddress,
13441422

13451423
BinaryFunction *BF = BC->getBinaryFunctionAtAddress(EntryAddress);
13461424
if (BF && BC->isAArch64()) {
1347-
// Handle IFUNC trampoline
1425+
// Handle IFUNC trampoline with symbol
13481426
setPLTSymbol(BF, BF->getOneName());
13491427
return;
13501428
}
13511429

13521430
const Relocation *Rel = BC->getDynamicRelocationAt(TargetAddress);
1353-
if (!Rel || !Rel->Symbol)
1431+
if (!Rel)
13541432
return;
13551433

1434+
MCSymbol *Symbol = Rel->Symbol;
1435+
if (!Symbol) {
1436+
if (!BC->isAArch64() || !Rel->Addend || !Rel->isIRelative())
1437+
return;
1438+
1439+
// IFUNC trampoline without symbol
1440+
BinaryFunction *TargetBF = BC->getBinaryFunctionAtAddress(Rel->Addend);
1441+
if (!TargetBF) {
1442+
errs()
1443+
<< "BOLT-WARNING: Expected BF to be presented as IFUNC resolver at "
1444+
<< Twine::utohexstr(Rel->Addend) << ", skipping\n";
1445+
return;
1446+
}
1447+
1448+
Symbol = TargetBF->getSymbol();
1449+
}
1450+
13561451
ErrorOr<BinarySection &> Section = BC->getSectionForAddress(EntryAddress);
13571452
assert(Section && "cannot get section for address");
13581453
if (!BF)
1359-
BF = BC->createBinaryFunction(Rel->Symbol->getName().str() + "@PLT",
1360-
*Section, EntryAddress, 0, EntrySize,
1454+
BF = BC->createBinaryFunction(Symbol->getName().str() + "@PLT", *Section,
1455+
EntryAddress, 0, EntrySize,
13611456
Section->getAlignment());
13621457
else
1363-
BF->addAlternativeName(Rel->Symbol->getName().str() + "@PLT");
1364-
setPLTSymbol(BF, Rel->Symbol->getName());
1458+
BF->addAlternativeName(Symbol->getName().str() + "@PLT");
1459+
setPLTSymbol(BF, Symbol->getName());
13651460
}
13661461

13671462
void RewriteInstance::disassemblePLTSectionAArch64(BinarySection &Section) {
@@ -5118,7 +5213,13 @@ Error RewriteInstance::readELFDynamic(ELFObjectFile<ELFT> *File) {
51185213
}
51195214
break;
51205215
case ELF::DT_FINI:
5121-
BC->FiniFunctionAddress = Dyn.getPtr();
5216+
BC->FiniAddress = Dyn.getPtr();
5217+
break;
5218+
case ELF::DT_FINI_ARRAY:
5219+
BC->FiniArrayAddress = Dyn.getPtr();
5220+
break;
5221+
case ELF::DT_FINI_ARRAYSZ:
5222+
BC->FiniArraySize = Dyn.getPtr();
51225223
break;
51235224
case ELF::DT_RELA:
51245225
DynamicRelocationsAddress = Dyn.getPtr();

bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ void HugifyRuntimeLibrary::link(BinaryContext &BC, StringRef ToolPath,
7171
"We don't currently support linking multiple runtime libraries");
7272
RuntimeStartAddress = Linker.lookupSymbol("__bolt_hugify_self").value_or(0);
7373
if (!RuntimeStartAddress) {
74-
errs() << "BOLT-ERROR: instrumentation library does not define "
75-
"__bolt_hugify_self: "
74+
errs() << "BOLT-ERROR: hugify library does not define __bolt_hugify_self: "
7675
<< LibPath << "\n";
7776
exit(1);
7877
}

bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,11 @@ void InstrumentationRuntimeLibrary::adjustCommandLineOptions(
5757
"the input binary\n";
5858
exit(1);
5959
}
60-
if (!BC.FiniFunctionAddress && !BC.IsStaticExecutable) {
61-
errs() << "BOLT-ERROR: input binary lacks DT_FINI entry in the dynamic "
62-
"section but instrumentation currently relies on patching "
63-
"DT_FINI to write the profile\n";
60+
61+
if (BC.IsStaticExecutable && !opts::InstrumentationSleepTime) {
62+
errs() << "BOLT-ERROR: instrumentation of static binary currently does not "
63+
"support profile output on binary finalization, so it "
64+
"requires -instrumentation-sleep-time=N (N>0) usage\n";
6465
exit(1);
6566
}
6667

@@ -89,13 +90,6 @@ void InstrumentationRuntimeLibrary::emitBinary(BinaryContext &BC,
8990
"__BOLT", "__counters", MachO::S_REGULAR,
9091
SectionKind::getData()));
9192

92-
if (BC.IsStaticExecutable && !opts::InstrumentationSleepTime) {
93-
errs() << "BOLT-ERROR: instrumentation of static binary currently does not "
94-
"support profile output on binary finalization, so it "
95-
"requires -instrumentation-sleep-time=N (N>0) usage\n";
96-
exit(1);
97-
}
98-
9993
Section->setAlignment(llvm::Align(BC.RegularPageSize));
10094
Streamer.switchSection(Section);
10195

bolt/test/AArch64/Inputs/iplt.ld

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SECTIONS {
2+
.plt : ALIGN(16) { *(.plt) *(.iplt) }
3+
}

0 commit comments

Comments
 (0)