Skip to content

Commit f3dbd98

Browse files
committed
merge main into amd-staging
2 parents efb57bd + 2871f69 commit f3dbd98

File tree

466 files changed

+16063
-2854
lines changed

Some content is hidden

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

466 files changed

+16063
-2854
lines changed

bolt/include/bolt/Rewrite/RewriteInstance.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,9 @@ class RewriteInstance {
505505
/// Number of local symbols in newly written symbol table.
506506
uint64_t NumLocalSymbols{0};
507507

508+
/// Flag indicating runtime library linking just started.
509+
bool StartLinkingRuntimeLib{false};
510+
508511
/// Information on special Procedure Linkage Table sections. There are
509512
/// multiple variants generated by different linkers.
510513
struct PLTSectionInfo {

bolt/lib/Passes/Instrumentation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ Error Instrumentation::runOnFunctions(BinaryContext &BC) {
604604
/*IsText=*/false,
605605
/*IsAllocatable=*/true);
606606
BC.registerOrUpdateSection(".bolt.instr.counters", ELF::SHT_PROGBITS, Flags,
607-
nullptr, 0, 1);
607+
nullptr, 0, BC.RegularPageSize);
608608

609609
BC.registerOrUpdateNoteSection(".bolt.instr.tables", nullptr, 0,
610610
/*Alignment=*/1,

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,11 @@ Error RewriteInstance::discoverStorage() {
628628
unsigned Phnum = Obj.getHeader().e_phnum;
629629
Phnum += 3;
630630

631+
// Reserve two more pheaders to avoid having writeable and executable
632+
// segment in instrumented binary.
633+
if (opts::Instrument)
634+
Phnum += 2;
635+
631636
NextAvailableAddress += Phnum * sizeof(ELF64LEPhdrTy);
632637
NextAvailableOffset += Phnum * sizeof(ELF64LEPhdrTy);
633638
}
@@ -2083,6 +2088,13 @@ void RewriteInstance::adjustCommandLineOptions() {
20832088
opts::HotText = false;
20842089
}
20852090

2091+
if (opts::Instrument && opts::UseGnuStack) {
2092+
BC->errs() << "BOLT-ERROR: cannot avoid having writeable and executable "
2093+
"segment in instrumented binary if program headers will be "
2094+
"updated in place\n";
2095+
exit(1);
2096+
}
2097+
20862098
if (opts::HotText && opts::HotTextMoveSections.getNumOccurrences() == 0) {
20872099
opts::HotTextMoveSections.addValue(".stub");
20882100
opts::HotTextMoveSections.addValue(".mover");
@@ -3612,11 +3624,13 @@ void RewriteInstance::emitAndLink() {
36123624
static_cast<MCObjectStreamer &>(*Streamer).getAssembler());
36133625
}
36143626

3615-
if (RuntimeLibrary *RtLibrary = BC->getRuntimeLibrary())
3627+
if (RuntimeLibrary *RtLibrary = BC->getRuntimeLibrary()) {
3628+
StartLinkingRuntimeLib = true;
36163629
RtLibrary->link(*BC, ToolPath, *Linker, [this](auto MapSection) {
36173630
// Map newly registered sections.
36183631
this->mapAllocatableSections(MapSection);
36193632
});
3633+
}
36203634

36213635
// Once the code is emitted, we can rename function sections to actual
36223636
// output sections and de-register sections used for emission.
@@ -4011,12 +4025,17 @@ void RewriteInstance::mapAllocatableSections(
40114025
Section.setOutputFileOffset(Section.getInputFileOffset());
40124026
MapSection(Section, Section.getAddress());
40134027
} else {
4014-
NextAvailableAddress =
4015-
alignTo(NextAvailableAddress, Section.getAlignment());
4028+
uint64_t Alignment = Section.getAlignment();
4029+
if (opts::Instrument && StartLinkingRuntimeLib) {
4030+
Alignment = BC->RegularPageSize;
4031+
StartLinkingRuntimeLib = false;
4032+
}
4033+
NextAvailableAddress = alignTo(NextAvailableAddress, Alignment);
4034+
40164035
LLVM_DEBUG({
4017-
dbgs() << "BOLT: mapping section " << Section.getName() << " (0x"
4018-
<< Twine::utohexstr(Section.getAllocAddress()) << ") to 0x"
4019-
<< Twine::utohexstr(NextAvailableAddress) << ":0x"
4036+
dbgs() << "BOLT-DEBUG: mapping section " << Section.getName()
4037+
<< " (0x" << Twine::utohexstr(Section.getAllocAddress())
4038+
<< ") to 0x" << Twine::utohexstr(NextAvailableAddress) << ":0x"
40204039
<< Twine::utohexstr(NextAvailableAddress +
40214040
Section.getOutputSize())
40224041
<< '\n';
@@ -4079,6 +4098,9 @@ void RewriteInstance::patchELFPHDRTable() {
40794098
}
40804099
}
40814100

4101+
if (opts::Instrument)
4102+
Phnum += 2;
4103+
40824104
// NOTE Currently .eh_frame_hdr appends to the last segment, recalculate
40834105
// last segments size based on the NextAvailableAddress variable.
40844106
if (!NewWritableSegmentSize) {
@@ -4093,7 +4115,8 @@ void RewriteInstance::patchELFPHDRTable() {
40934115
const uint64_t SavedPos = OS.tell();
40944116
OS.seek(PHDRTableOffset);
40954117

4096-
auto createNewTextPhdr = [&]() {
4118+
auto createNewPhdrs = [&]() {
4119+
SmallVector<ELF64LEPhdrTy, 3> NewPhdrs;
40974120
ELF64LEPhdrTy NewPhdr;
40984121
NewPhdr.p_type = ELF::PT_LOAD;
40994122
if (PHDRTableAddress) {
@@ -4108,20 +4131,67 @@ void RewriteInstance::patchELFPHDRTable() {
41084131
NewPhdr.p_filesz = NewTextSegmentSize;
41094132
NewPhdr.p_memsz = NewTextSegmentSize;
41104133
NewPhdr.p_flags = ELF::PF_X | ELF::PF_R;
4111-
if (opts::Instrument) {
4112-
// FIXME: Currently instrumentation is experimental and the runtime data
4113-
// is emitted with code, thus everything needs to be writable.
4114-
NewPhdr.p_flags |= ELF::PF_W;
4115-
}
41164134
NewPhdr.p_align = BC->PageAlign;
41174135

4118-
return NewPhdr;
4136+
if (!opts::Instrument) {
4137+
NewPhdrs.push_back(NewPhdr);
4138+
} else {
4139+
ErrorOr<BinarySection &> Sec =
4140+
BC->getUniqueSectionByName(".bolt.instr.counters");
4141+
assert(Sec && "expected one and only one `.bolt.instr.counters` section");
4142+
const uint64_t Addr = Sec->getOutputAddress();
4143+
const uint64_t Offset = Sec->getOutputFileOffset();
4144+
const uint64_t Size = Sec->getOutputSize();
4145+
assert(Addr > NewPhdr.p_vaddr &&
4146+
Addr + Size < NewPhdr.p_vaddr + NewPhdr.p_memsz &&
4147+
"`.bolt.instr.counters` section is expected to be included in the "
4148+
"new text sgement");
4149+
4150+
// Set correct size for the previous header since we are breaking the
4151+
// new text segment into three segments.
4152+
uint64_t Delta = Addr - NewPhdr.p_vaddr;
4153+
NewPhdr.p_filesz = Delta;
4154+
NewPhdr.p_memsz = Delta;
4155+
NewPhdrs.push_back(NewPhdr);
4156+
4157+
// Create a program header for a RW segment that includes the
4158+
// `.bolt.instr.counters` section only.
4159+
ELF64LEPhdrTy NewPhdrRWSegment;
4160+
NewPhdrRWSegment.p_type = ELF::PT_LOAD;
4161+
NewPhdrRWSegment.p_offset = Offset;
4162+
NewPhdrRWSegment.p_vaddr = Addr;
4163+
NewPhdrRWSegment.p_paddr = Addr;
4164+
NewPhdrRWSegment.p_filesz = Size;
4165+
NewPhdrRWSegment.p_memsz = Size;
4166+
NewPhdrRWSegment.p_flags = ELF::PF_R | ELF::PF_W;
4167+
NewPhdrRWSegment.p_align = BC->RegularPageSize;
4168+
NewPhdrs.push_back(NewPhdrRWSegment);
4169+
4170+
// Create a program header for a RX segment that includes all the RX
4171+
// sections from runtime library.
4172+
ELF64LEPhdrTy NewPhdrRXSegment;
4173+
NewPhdrRXSegment.p_type = ELF::PT_LOAD;
4174+
const uint64_t AddrRX = alignTo(Addr + Size, BC->RegularPageSize);
4175+
const uint64_t OffsetRX = alignTo(Offset + Size, BC->RegularPageSize);
4176+
const uint64_t SizeRX = NewTextSegmentSize - (AddrRX - NewPhdr.p_paddr);
4177+
NewPhdrRXSegment.p_offset = OffsetRX;
4178+
NewPhdrRXSegment.p_vaddr = AddrRX;
4179+
NewPhdrRXSegment.p_paddr = AddrRX;
4180+
NewPhdrRXSegment.p_filesz = SizeRX;
4181+
NewPhdrRXSegment.p_memsz = SizeRX;
4182+
NewPhdrRXSegment.p_flags = ELF::PF_X | ELF::PF_R;
4183+
NewPhdrRXSegment.p_align = BC->RegularPageSize;
4184+
NewPhdrs.push_back(NewPhdrRXSegment);
4185+
}
4186+
4187+
return NewPhdrs;
41194188
};
41204189

41214190
auto writeNewSegmentPhdrs = [&]() {
41224191
if (PHDRTableAddress || NewTextSegmentSize) {
4123-
ELF64LE::Phdr NewPhdr = createNewTextPhdr();
4124-
OS.write(reinterpret_cast<const char *>(&NewPhdr), sizeof(NewPhdr));
4192+
SmallVector<ELF64LE::Phdr, 3> NewPhdrs = createNewPhdrs();
4193+
OS.write(reinterpret_cast<const char *>(NewPhdrs.data()),
4194+
sizeof(ELF64LE::Phdr) * NewPhdrs.size());
41254195
}
41264196

41274197
if (NewWritableSegmentSize) {
@@ -4169,8 +4239,12 @@ void RewriteInstance::patchELFPHDRTable() {
41694239
}
41704240
case ELF::PT_GNU_STACK:
41714241
if (opts::UseGnuStack) {
4172-
// Overwrite the header with the new text segment header.
4173-
NewPhdr = createNewTextPhdr();
4242+
// Overwrite the header with the new segment header.
4243+
assert(!opts::Instrument);
4244+
SmallVector<ELF64LE::Phdr, 3> NewPhdrs = createNewPhdrs();
4245+
assert(NewPhdrs.size() == 1 &&
4246+
"expect exactly one program header was created");
4247+
NewPhdr = NewPhdrs[0];
41744248
ModdedGnuStack = true;
41754249
}
41764250
break;

bolt/test/avoid-wx-segment.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Test bolt instrumentation won't generate a binary with any segment that
2+
// is writable and executable. Basically we want to put `.bolt.instr.counters`
3+
// section into its own segment, separated from its surrounding RX sections.
4+
5+
// REQUIRES: system-linux
6+
7+
void foo() {}
8+
void bar() { foo(); }
9+
10+
// RUN: %clang %cflags -c %s -o %t.o
11+
// RUN: ld.lld -q -o %t.so %t.o -shared --init=foo --fini=foo
12+
// RUN: llvm-bolt --instrument %t.so -o %tt.so
13+
// RUN: llvm-readelf -l %tt.so | FileCheck %s
14+
// CHECK-NOT: RWE
15+
// CHECK: {{[0-9]*}} .bolt.instr.counters {{$}}

clang-tools-extra/clangd/refactor/Rename.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,8 @@ const NamedDecl *lookupSiblingWithinEnclosingScope(ASTContext &Ctx,
338338
for (const auto &Child : DS->getDeclGroup())
339339
if (const auto *ND = dyn_cast<NamedDecl>(Child))
340340
if (ND != &RenamedDecl && ND->getDeclName().isIdentifier() &&
341-
ND->getName() == Name)
341+
ND->getName() == Name &&
342+
ND->getIdentifierNamespace() & RenamedDecl.getIdentifierNamespace())
342343
return ND;
343344
return nullptr;
344345
};
@@ -380,7 +381,9 @@ const NamedDecl *lookupSiblingWithinEnclosingScope(ASTContext &Ctx,
380381
// Also check if there is a name collision with function arguments.
381382
if (const auto *Function = ScopeParent->get<FunctionDecl>())
382383
for (const auto *Parameter : Function->parameters())
383-
if (Parameter->getName() == NewName)
384+
if (Parameter->getName() == NewName &&
385+
Parameter->getIdentifierNamespace() &
386+
RenamedDecl.getIdentifierNamespace())
384387
return Parameter;
385388
return nullptr;
386389
}
@@ -405,7 +408,9 @@ const NamedDecl *lookupSiblingWithinEnclosingScope(ASTContext &Ctx,
405408
if (const auto *EnclosingFunction = Parent->get<FunctionDecl>()) {
406409
// Check for conflicts with other arguments.
407410
for (const auto *Parameter : EnclosingFunction->parameters())
408-
if (Parameter != &RenamedDecl && Parameter->getName() == NewName)
411+
if (Parameter != &RenamedDecl && Parameter->getName() == NewName &&
412+
Parameter->getIdentifierNamespace() &
413+
RenamedDecl.getIdentifierNamespace())
409414
return Parameter;
410415
// FIXME: We don't modify all references to function parameters when
411416
// renaming from forward declaration now, so using a name colliding with
@@ -450,7 +455,8 @@ const NamedDecl *lookupSiblingsWithinContext(ASTContext &Ctx,
450455
}
451456
// Lookup may contain the RenameDecl itself, exclude it.
452457
for (const auto *D : LookupResult)
453-
if (D->getCanonicalDecl() != RenamedDecl.getCanonicalDecl())
458+
if (D->getCanonicalDecl() != RenamedDecl.getCanonicalDecl() &&
459+
D->getIdentifierNamespace() & RenamedDecl.getIdentifierNamespace())
454460
return D;
455461
return nullptr;
456462
}

clang-tools-extra/clangd/unittests/RenameTests.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,39 @@ TEST(RenameTest, Renameable) {
12691269
)cpp",
12701270
"conflict", !HeaderFile, "Conflict"},
12711271

1272+
{R"cpp(
1273+
struct conflict {};
1274+
enum v^ar {};
1275+
)cpp",
1276+
"conflict", !HeaderFile, "conflict"},
1277+
1278+
{R"cpp(
1279+
struct conflict {};
1280+
int [[v^ar]];
1281+
)cpp",
1282+
nullptr, !HeaderFile, "conflict"},
1283+
1284+
{R"cpp(
1285+
enum conflict {};
1286+
int [[v^ar]];
1287+
)cpp",
1288+
nullptr, !HeaderFile, "conflict"},
1289+
1290+
{R"cpp(
1291+
void func(int conflict) {
1292+
struct [[t^ag]] {};
1293+
}
1294+
)cpp",
1295+
nullptr, !HeaderFile, "conflict"},
1296+
1297+
{R"cpp(
1298+
void func(void) {
1299+
struct conflict {};
1300+
int [[v^ar]];
1301+
}
1302+
)cpp",
1303+
nullptr, !HeaderFile, "conflict"},
1304+
12721305
{R"cpp(
12731306
void func(int);
12741307
void [[o^therFunc]](double);

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,9 +2582,9 @@ the configuration (without a prefix: ``Auto``).
25822582

25832583
.. _BracedInitializerIndentWidth:
25842584

2585-
**BracedInitializerIndentWidth** (``Unsigned``) :versionbadge:`clang-format 17` :ref:`<BracedInitializerIndentWidth>`
2585+
**BracedInitializerIndentWidth** (``Integer``) :versionbadge:`clang-format 17` :ref:`<BracedInitializerIndentWidth>`
25862586
The number of columns to use to indent the contents of braced init lists.
2587-
If unset, ``ContinuationIndentWidth`` is used.
2587+
If unset or negative, ``ContinuationIndentWidth`` is used.
25882588

25892589
.. code-block:: c++
25902590

0 commit comments

Comments
 (0)