Skip to content

Commit 278a983

Browse files
author
Pavel V Chupin
committed
Merge from 'main' to 'sycl-web' (339 commits)
CONFLICT (content): Merge conflict in clang/lib/Driver/Types.cpp CONFLICT (content): Merge conflict in clang/include/clang/Basic/DiagnosticDriverKinds.td
2 parents 901b4ed + 721651b commit 278a983

File tree

1,171 files changed

+38917
-13762
lines changed

Some content is hidden

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

1,171 files changed

+38917
-13762
lines changed

bolt/CMakeLists.txt

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -59,31 +59,8 @@ if (BOLT_ENABLE_RUNTIME)
5959
COMPONENT bolt)
6060
endif()
6161

62-
# Get the current git revision for BOLT.
63-
find_program(git_executable NAMES git git.exe git.cmd)
64-
if (git_executable)
65-
execute_process(COMMAND ${git_executable} rev-parse HEAD
66-
WORKING_DIRECTORY ${LLVM_MAIN_SRC_DIR}
67-
TIMEOUT 5
68-
RESULT_VARIABLE git_result
69-
OUTPUT_VARIABLE git_output)
70-
if( git_result EQUAL 0 )
71-
string(STRIP "${git_output}" git_ref_id)
72-
set(BOLT_REVISION "${git_ref_id}")
73-
endif()
74-
endif()
75-
7662
find_program(GNU_LD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.bfd ld.bfd DOC "GNU ld")
7763

78-
# If we can't find a revision, set it to "<unknown>".
79-
if (NOT BOLT_REVISION)
80-
set(BOLT_REVISION "<unknown>")
81-
endif()
82-
83-
configure_file(
84-
${CMAKE_CURRENT_SOURCE_DIR}/include/bolt/Utils/BoltRevision.inc.in
85-
${CMAKE_CURRENT_BINARY_DIR}/include/bolt/Utils/BoltRevision.inc)
86-
8764
include_directories(
8865
${CMAKE_CURRENT_SOURCE_DIR}/include
8966
${CMAKE_CURRENT_BINARY_DIR}/include

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,15 @@ class BinaryContext {
970970
Sections.end()));
971971
}
972972

973+
/// Return base address for the shared object or PIE based on the segment
974+
/// mapping information. \p MMapAddress is an address where one of the
975+
/// segments was mapped. \p FileOffset is the offset in the file of the
976+
/// mapping. Note that \p FileOffset should be page-aligned and could be
977+
/// different from the file offset of the segment which could be unaligned.
978+
/// If no segment is found that matches \p FileOffset, return NoneType().
979+
Optional<uint64_t> getBaseAddressForMapping(uint64_t MMapAddress,
980+
uint64_t FileOffset) const;
981+
973982
/// Check if the address belongs to this binary's static allocation space.
974983
bool containsAddress(uint64_t Address) const {
975984
return Address >= FirstAllocAddress && Address < LayoutStartAddress;

bolt/include/bolt/Profile/DataAggregator.h

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,15 @@ class DataAggregator : public DataReader {
168168
/// from the file name in BC.
169169
std::string BuildIDBinaryName;
170170

171-
/// Memory map info for a single file
171+
/// Memory map info for a single file as recorded in perf.data
172172
struct MMapInfo {
173-
uint64_t BaseAddress;
174-
uint64_t Size;
175-
uint64_t Offset;
176-
int32_t PID{-1};
177-
bool Forked{false};
178-
uint64_t Time{0ULL}; // time in micro seconds
173+
uint64_t BaseAddress{0}; /// Base address of the mapped binary.
174+
uint64_t MMapAddress{0}; /// Address of the executable segment.
175+
uint64_t Size{0}; /// Size of the mapping.
176+
uint64_t Offset{0}; /// File offset of the mapped segment.
177+
int32_t PID{-1}; /// Process ID.
178+
bool Forked{false}; /// Was the process forked?
179+
uint64_t Time{0ULL}; /// Time in micro seconds.
179180
};
180181

181182
/// Per-PID map info for the binary
@@ -420,12 +421,8 @@ class DataAggregator : public DataReader {
420421
/// correspond to the binary allocated address space, are adjusted to avoid
421422
/// conflicts.
422423
void adjustAddress(uint64_t &Address, const MMapInfo &MMI) const {
423-
if (Address >= MMI.BaseAddress && Address < MMI.BaseAddress + MMI.Size) {
424-
// NOTE: Assumptions about the binary segment load table (PH for ELF)
425-
// Segment file offset equals virtual address (which is true for .so)
426-
// There aren't multiple executable segments loaded because MMapInfo
427-
// doesn't support them.
428-
Address -= MMI.BaseAddress - MMI.Offset;
424+
if (Address >= MMI.MMapAddress && Address < MMI.MMapAddress + MMI.Size) {
425+
Address -= MMI.BaseAddress;
429426
} else if (Address < MMI.Size) {
430427
// Make sure the address is not treated as belonging to the binary.
431428
Address = (-1ULL);

bolt/include/bolt/Utils/BoltRevision.inc.in

Lines changed: 0 additions & 1 deletion
This file was deleted.

bolt/lib/Core/BinaryContext.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,22 @@ void BinaryContext::printInstruction(raw_ostream &OS, const MCInst &Instruction,
16901690
}
16911691
}
16921692

1693+
Optional<uint64_t>
1694+
BinaryContext::getBaseAddressForMapping(uint64_t MMapAddress,
1695+
uint64_t FileOffset) const {
1696+
// Find a segment with a matching file offset.
1697+
for (auto &KV : SegmentMapInfo) {
1698+
const SegmentInfo &SegInfo = KV.second;
1699+
if (alignDown(SegInfo.FileOffset, SegInfo.Alignment) == FileOffset) {
1700+
// Use segment's aligned memory offset to calculate the base address.
1701+
const uint64_t MemOffset = alignDown(SegInfo.Address, SegInfo.Alignment);
1702+
return MMapAddress - MemOffset;
1703+
}
1704+
}
1705+
1706+
return NoneType();
1707+
}
1708+
16931709
ErrorOr<BinarySection &> BinaryContext::getSectionForAddress(uint64_t Address) {
16941710
auto SI = AddressToSection.upper_bound(Address);
16951711
if (SI != AddressToSection.begin()) {

bolt/lib/Core/Relocation.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,16 +168,17 @@ bool skipRelocationProcessX86(uint64_t Type, uint64_t Contents) {
168168
bool skipRelocationProcessAArch64(uint64_t Type, uint64_t Contents) {
169169
auto IsMov = [](uint64_t Contents) -> bool {
170170
// The bits 28-23 are 0b100101
171-
if ((Contents & 0x1f800000) == 0x12800000)
172-
return true;
173-
return false;
171+
return (Contents & 0x1f800000) == 0x12800000;
174172
};
175173

176174
auto IsB = [](uint64_t Contents) -> bool {
177175
// The bits 31-26 are 0b000101
178-
if ((Contents & 0xfc000000) == 0x14000000)
179-
return true;
180-
return false;
176+
return (Contents & 0xfc000000) == 0x14000000;
177+
};
178+
179+
auto IsAdr = [](uint64_t Contents) -> bool {
180+
// The bits 31-24 are 0b0xx10000
181+
return (Contents & 0x9f000000) == 0x10000000;
181182
};
182183

183184
auto IsNop = [](uint64_t Contents) -> bool { return Contents == 0xd503201f; };
@@ -205,7 +206,7 @@ bool skipRelocationProcessAArch64(uint64_t Type, uint64_t Contents) {
205206
}
206207
}
207208

208-
// The ld might replace load/store instruction with jump and
209+
// The linker might replace load/store instruction with jump and
209210
// veneer due to errata 843419
210211
// https://documentation-service.arm.com/static/5fa29fddb209f547eebd361d
211212
// Thus load/store relocations for these instructions must be ignored
@@ -223,6 +224,18 @@ bool skipRelocationProcessAArch64(uint64_t Type, uint64_t Contents) {
223224
}
224225
}
225226

227+
// The linker might relax ADRP+ADD or ADRP+LDR sequences to the ADR+NOP
228+
switch (Type) {
229+
default:
230+
break;
231+
case ELF::R_AARCH64_ADR_PREL_PG_HI21:
232+
case ELF::R_AARCH64_ADD_ABS_LO12_NC:
233+
case ELF::R_AARCH64_ADR_GOT_PAGE:
234+
case ELF::R_AARCH64_LD64_GOT_LO12_NC:
235+
if (IsAdr(Contents))
236+
return true;
237+
}
238+
226239
return false;
227240
}
228241

bolt/lib/Passes/BinaryPasses.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,7 @@ uint64_t ShortenInstructions::shortenInstructions(BinaryFunction &Function) {
10151015
continue;
10161016

10171017
if (opts::Verbosity > 2) {
1018+
BC.scopeLock();
10181019
outs() << "BOLT-INFO: shortening:\nBOLT-INFO: ";
10191020
BC.printInstruction(outs(), OriginalInst, 0, &Function);
10201021
outs() << "BOLT-INFO: to:";

bolt/lib/Profile/DataAggregator.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,7 +1943,7 @@ DataAggregator::parseMMapEvent() {
19431943
}
19441944

19451945
const StringRef BaseAddressStr = Line.split('[').second.split('(').first;
1946-
if (BaseAddressStr.getAsInteger(0, ParsedInfo.BaseAddress)) {
1946+
if (BaseAddressStr.getAsInteger(0, ParsedInfo.MMapAddress)) {
19471947
reportError("expected base address");
19481948
Diag << "Found: " << BaseAddressStr << "in '" << Line << "'\n";
19491949
return make_error_code(llvm::errc::io_error);
@@ -2003,7 +2003,7 @@ std::error_code DataAggregator::parseMMapEvents() {
20032003
dbgs() << "FileName -> mmap info:\n";
20042004
for (const std::pair<const StringRef, MMapInfo> &Pair : GlobalMMapInfo)
20052005
dbgs() << " " << Pair.first << " : " << Pair.second.PID << " [0x"
2006-
<< Twine::utohexstr(Pair.second.BaseAddress) << ", "
2006+
<< Twine::utohexstr(Pair.second.MMapAddress) << ", "
20072007
<< Twine::utohexstr(Pair.second.Size) << " @ "
20082008
<< Twine::utohexstr(Pair.second.Offset) << "]\n";
20092009
});
@@ -2017,29 +2017,45 @@ std::error_code DataAggregator::parseMMapEvents() {
20172017

20182018
auto Range = GlobalMMapInfo.equal_range(NameToUse);
20192019
for (auto I = Range.first; I != Range.second; ++I) {
2020-
const MMapInfo &MMapInfo = I->second;
2021-
if (BC->HasFixedLoadAddress && MMapInfo.BaseAddress) {
2020+
MMapInfo &MMapInfo = I->second;
2021+
if (BC->HasFixedLoadAddress && MMapInfo.MMapAddress) {
20222022
// Check that the binary mapping matches one of the segments.
20232023
bool MatchFound = false;
20242024
for (auto &KV : BC->SegmentMapInfo) {
20252025
SegmentInfo &SegInfo = KV.second;
2026-
// The mapping is page-aligned and hence the BaseAddress could be
2026+
// The mapping is page-aligned and hence the MMapAddress could be
20272027
// different from the segment start address. We cannot know the page
20282028
// size of the mapping, but we know it should not exceed the segment
20292029
// alignment value. Hence we are performing an approximate check.
2030-
if (SegInfo.Address >= MMapInfo.BaseAddress &&
2031-
SegInfo.Address - MMapInfo.BaseAddress < SegInfo.Alignment) {
2030+
if (SegInfo.Address >= MMapInfo.MMapAddress &&
2031+
SegInfo.Address - MMapInfo.MMapAddress < SegInfo.Alignment) {
20322032
MatchFound = true;
20332033
break;
20342034
}
20352035
}
20362036
if (!MatchFound) {
20372037
errs() << "PERF2BOLT-WARNING: ignoring mapping of " << NameToUse
2038-
<< " at 0x" << Twine::utohexstr(MMapInfo.BaseAddress) << '\n';
2038+
<< " at 0x" << Twine::utohexstr(MMapInfo.MMapAddress) << '\n';
20392039
continue;
20402040
}
20412041
}
20422042

2043+
// Set base address for shared objects.
2044+
if (!BC->HasFixedLoadAddress) {
2045+
Optional<uint64_t> BaseAddress =
2046+
BC->getBaseAddressForMapping(MMapInfo.MMapAddress, MMapInfo.Offset);
2047+
if (!BaseAddress) {
2048+
errs() << "PERF2BOLT-WARNING: unable to find base address of the "
2049+
"binary when memory mapped at 0x"
2050+
<< Twine::utohexstr(MMapInfo.MMapAddress)
2051+
<< " using file offset 0x" << Twine::utohexstr(MMapInfo.Offset)
2052+
<< ". Ignoring profile data for this mapping\n";
2053+
continue;
2054+
} else {
2055+
MMapInfo.BaseAddress = *BaseAddress;
2056+
}
2057+
}
2058+
20432059
BinaryMMapInfo.insert(std::make_pair(MMapInfo.PID, MMapInfo));
20442060
}
20452061

@@ -2110,7 +2126,7 @@ std::error_code DataAggregator::parseTaskEvents() {
21102126
LLVM_DEBUG({
21112127
for (std::pair<const uint64_t, MMapInfo> &MMI : BinaryMMapInfo)
21122128
outs() << " " << MMI.second.PID << (MMI.second.Forked ? " (forked)" : "")
2113-
<< ": (0x" << Twine::utohexstr(MMI.second.BaseAddress) << ": 0x"
2129+
<< ": (0x" << Twine::utohexstr(MMI.second.MMapAddress) << ": 0x"
21142130
<< Twine::utohexstr(MMI.second.Size) << ")\n";
21152131
});
21162132

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,50 +2404,57 @@ void RewriteInstance::readRelocations(const SectionRef &Section) {
24042404
}
24052405

24062406
MCSymbol *ReferencedSymbol = nullptr;
2407-
if (!IsSectionRelocation) {
2407+
if (!IsSectionRelocation)
24082408
if (BinaryData *BD = BC->getBinaryDataByName(SymbolName))
24092409
ReferencedSymbol = BD->getSymbol();
2410-
}
24112410

2412-
// PC-relative relocations from data to code are tricky since the original
2413-
// information is typically lost after linking even with '--emit-relocs'.
2414-
// They are normally used by PIC-style jump tables and reference both
2415-
// the jump table and jump destination by computing the difference
2416-
// between the two. If we blindly apply the relocation it will appear
2417-
// that it references an arbitrary location in the code, possibly even
2418-
// in a different function from that containing the jump table.
2411+
ErrorOr<BinarySection &> ReferencedSection =
2412+
BC->getSectionForAddress(SymbolAddress);
2413+
2414+
const bool IsToCode = ReferencedSection && ReferencedSection->isText();
2415+
2416+
// Special handling of PC-relative relocations.
24192417
if (!IsAArch64 && Relocation::isPCRelative(RType)) {
2420-
// For relocations against non-code sections, just register the fact that
2421-
// we have a PC-relative relocation at a given address. The actual
2422-
// referenced label/address cannot be determined from linker data alone.
2423-
if (!IsFromCode)
2418+
if (!IsFromCode && IsToCode) {
2419+
// PC-relative relocations from data to code are tricky since the
2420+
// original information is typically lost after linking, even with
2421+
// '--emit-relocs'. Such relocations are normally used by PIC-style
2422+
// jump tables and they reference both the jump table and jump
2423+
// targets by computing the difference between the two. If we blindly
2424+
// apply the relocation, it will appear that it references an arbitrary
2425+
// location in the code, possibly in a different function from the one
2426+
// containing the jump table.
2427+
//
2428+
// For that reason, we only register the fact that there is a
2429+
// PC-relative relocation at a given address against the code.
2430+
// The actual referenced label/address will be determined during jump
2431+
// table analysis.
24242432
BC->addPCRelativeDataRelocation(Rel.getOffset());
2425-
else if (!IsSectionRelocation && ReferencedSymbol)
2433+
} else if (ContainingBF && !IsSectionRelocation && ReferencedSymbol) {
2434+
// If we know the referenced symbol, register the relocation from
2435+
// the code. It's required to properly handle cases where
2436+
// "symbol + addend" references an object different from "symbol".
24262437
ContainingBF->addRelocation(Rel.getOffset(), ReferencedSymbol, RType,
24272438
Addend, ExtractedValue);
2428-
else
2439+
} else {
24292440
LLVM_DEBUG(
24302441
dbgs() << "BOLT-DEBUG: not creating PC-relative relocation at 0x"
24312442
<< Twine::utohexstr(Rel.getOffset()) << " for " << SymbolName
24322443
<< "\n");
2444+
}
2445+
24332446
continue;
24342447
}
24352448

24362449
bool ForceRelocation = BC->forceSymbolRelocations(SymbolName);
2437-
ErrorOr<BinarySection &> RefSection =
2438-
std::make_error_code(std::errc::bad_address);
2439-
if (BC->isAArch64() && Relocation::isGOT(RType)) {
2450+
if (BC->isAArch64() && Relocation::isGOT(RType))
24402451
ForceRelocation = true;
2441-
} else {
2442-
RefSection = BC->getSectionForAddress(SymbolAddress);
2443-
if (!RefSection && !ForceRelocation) {
2444-
LLVM_DEBUG(
2445-
dbgs() << "BOLT-DEBUG: cannot determine referenced section.\n");
2446-
continue;
2447-
}
2448-
}
24492452

2450-
const bool IsToCode = RefSection && RefSection->isText();
2453+
if (!ReferencedSection && !ForceRelocation) {
2454+
LLVM_DEBUG(
2455+
dbgs() << "BOLT-DEBUG: cannot determine referenced section.\n");
2456+
continue;
2457+
}
24512458

24522459
// Occasionally we may see a reference past the last byte of the function
24532460
// typically as a result of __builtin_unreachable(). Check it here.
@@ -2474,8 +2481,8 @@ void RewriteInstance::readRelocations(const SectionRef &Section) {
24742481
}
24752482
}
24762483
} else if (ReferencedBF) {
2477-
assert(RefSection && "section expected for section relocation");
2478-
if (*ReferencedBF->getOriginSection() != *RefSection) {
2484+
assert(ReferencedSection && "section expected for section relocation");
2485+
if (*ReferencedBF->getOriginSection() != *ReferencedSection) {
24792486
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: ignoring false function reference\n");
24802487
ReferencedBF = nullptr;
24812488
}
@@ -2643,7 +2650,7 @@ void RewriteInstance::readRelocations(const SectionRef &Section) {
26432650
NumDataRelocations < opts::MaxDataRelocations);
26442651
};
26452652

2646-
if ((RefSection && refersToReorderedSection(RefSection)) ||
2653+
if ((ReferencedSection && refersToReorderedSection(ReferencedSection)) ||
26472654
(opts::ForceToDataRelocations && checkMaxDataRelocations()))
26482655
ForceRelocation = true;
26492656

bolt/lib/Utils/CommandLineOpts.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,18 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "bolt/Utils/CommandLineOpts.h"
14-
#include "bolt/Utils/BoltRevision.inc"
14+
#include "llvm/Support/VCSRevision.h"
1515

1616
using namespace llvm;
1717

1818
namespace llvm {
1919
namespace bolt {
20-
const char *BoltRevision = BOLT_VERSION_STRING;
20+
const char *BoltRevision =
21+
#ifdef LLVM_REVISION
22+
LLVM_REVISION;
23+
#else
24+
"<unknown>";
25+
#endif
2126
}
2227
}
2328

0 commit comments

Comments
 (0)