aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/XRay
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /llvm/lib/XRay
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
downloadsrc-cfca06d7963fa0909f90483b42a6d7d194d01e08.tar.gz
src-cfca06d7963fa0909f90483b42a6d7d194d01e08.zip
Vendor import of llvm-project master 2e10b7a39b9, the last commit beforevendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9vendor/llvm-project/master
the llvmorg-12-init tag, from which release/11.x was branched.
Notes
Notes: svn path=/vendor/llvm-project/master/; revision=363578 svn path=/vendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9/; revision=363579; tag=vendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9
Diffstat (limited to 'llvm/lib/XRay')
-rw-r--r--llvm/lib/XRay/FDRTraceExpander.cpp6
-rw-r--r--llvm/lib/XRay/FDRTraceWriter.cpp14
-rw-r--r--llvm/lib/XRay/InstrumentationMap.cpp76
-rw-r--r--llvm/lib/XRay/Trace.cpp1
4 files changed, 64 insertions, 33 deletions
diff --git a/llvm/lib/XRay/FDRTraceExpander.cpp b/llvm/lib/XRay/FDRTraceExpander.cpp
index cb7f66bccd7e..b68e997fe706 100644
--- a/llvm/lib/XRay/FDRTraceExpander.cpp
+++ b/llvm/lib/XRay/FDRTraceExpander.cpp
@@ -44,7 +44,7 @@ Error TraceExpander::visit(CustomEventRecord &R) {
CurrentRecord.PId = PID;
CurrentRecord.TId = TID;
CurrentRecord.Type = RecordTypes::CUSTOM_EVENT;
- CurrentRecord.Data = R.data();
+ CurrentRecord.Data = std::string(R.data());
BuildingRecord = true;
}
return Error::success();
@@ -59,7 +59,7 @@ Error TraceExpander::visit(CustomEventRecordV5 &R) {
CurrentRecord.PId = PID;
CurrentRecord.TId = TID;
CurrentRecord.Type = RecordTypes::CUSTOM_EVENT;
- CurrentRecord.Data = R.data();
+ CurrentRecord.Data = std::string(R.data());
BuildingRecord = true;
}
return Error::success();
@@ -75,7 +75,7 @@ Error TraceExpander::visit(TypedEventRecord &R) {
CurrentRecord.TId = TID;
CurrentRecord.RecordType = R.eventType();
CurrentRecord.Type = RecordTypes::TYPED_EVENT;
- CurrentRecord.Data = R.data();
+ CurrentRecord.Data = std::string(R.data());
BuildingRecord = true;
}
return Error::success();
diff --git a/llvm/lib/XRay/FDRTraceWriter.cpp b/llvm/lib/XRay/FDRTraceWriter.cpp
index f50dc19b4be8..71c09bd4fce4 100644
--- a/llvm/lib/XRay/FDRTraceWriter.cpp
+++ b/llvm/lib/XRay/FDRTraceWriter.cpp
@@ -20,10 +20,9 @@ namespace {
template <size_t Index> struct IndexedWriter {
template <
class Tuple,
- typename std::enable_if<
- (Index <
- std::tuple_size<typename std::remove_reference<Tuple>::type>::value),
- int>::type = 0>
+ std::enable_if_t<(Index <
+ std::tuple_size<std::remove_reference_t<Tuple>>::value),
+ int> = 0>
static size_t write(support::endian::Writer &OS, Tuple &&T) {
OS.write(std::get<Index>(T));
return sizeof(std::get<Index>(T)) + IndexedWriter<Index + 1>::write(OS, T);
@@ -31,10 +30,9 @@ template <size_t Index> struct IndexedWriter {
template <
class Tuple,
- typename std::enable_if<
- (Index >=
- std::tuple_size<typename std::remove_reference<Tuple>::type>::value),
- int>::type = 0>
+ std::enable_if_t<(Index >=
+ std::tuple_size<std::remove_reference_t<Tuple>>::value),
+ int> = 0>
static size_t write(support::endian::Writer &OS, Tuple &&) {
return 0;
}
diff --git a/llvm/lib/XRay/InstrumentationMap.cpp b/llvm/lib/XRay/InstrumentationMap.cpp
index 1e9b69a5f9dc..de0a9e60a511 100644
--- a/llvm/lib/XRay/InstrumentationMap.cpp
+++ b/llvm/lib/XRay/InstrumentationMap.cpp
@@ -52,26 +52,31 @@ using RelocMap = DenseMap<uint64_t, uint64_t>;
static Error
loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
- InstrumentationMap::SledContainer &Sleds,
- InstrumentationMap::FunctionAddressMap &FunctionAddresses,
- InstrumentationMap::FunctionAddressReverseMap &FunctionIds) {
+ InstrumentationMap::SledContainer &Sleds,
+ InstrumentationMap::FunctionAddressMap &FunctionAddresses,
+ InstrumentationMap::FunctionAddressReverseMap &FunctionIds) {
InstrumentationMap Map;
// Find the section named "xray_instr_map".
if ((!ObjFile.getBinary()->isELF() && !ObjFile.getBinary()->isMachO()) ||
!(ObjFile.getBinary()->getArch() == Triple::x86_64 ||
ObjFile.getBinary()->getArch() == Triple::ppc64le ||
+ ObjFile.getBinary()->getArch() == Triple::arm ||
ObjFile.getBinary()->getArch() == Triple::aarch64))
return make_error<StringError>(
- "File format not supported (only does ELF and Mach-O little endian 64-bit).",
+ "File format not supported (only does ELF and Mach-O little endian "
+ "64-bit).",
std::make_error_code(std::errc::not_supported));
StringRef Contents = "";
const auto &Sections = ObjFile.getBinary()->sections();
+ uint64_t Address = 0;
auto I = llvm::find_if(Sections, [&](object::SectionRef Section) {
Expected<StringRef> NameOrErr = Section.getName();
- if (NameOrErr)
+ if (NameOrErr) {
+ Address = Section.getAddress();
return *NameOrErr == "xray_instr_map";
+ }
consumeError(NameOrErr.takeError());
return false;
});
@@ -91,11 +96,14 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
uint32_t RelativeRelocation = [](object::ObjectFile *ObjFile) {
if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(ObjFile))
return ELFObj->getELFFile()->getRelativeRelocationType();
- else if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(ObjFile))
+ else if (const auto *ELFObj =
+ dyn_cast<object::ELF32BEObjectFile>(ObjFile))
return ELFObj->getELFFile()->getRelativeRelocationType();
- else if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(ObjFile))
+ else if (const auto *ELFObj =
+ dyn_cast<object::ELF64LEObjectFile>(ObjFile))
return ELFObj->getELFFile()->getRelativeRelocationType();
- else if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(ObjFile))
+ else if (const auto *ELFObj =
+ dyn_cast<object::ELF64BEObjectFile>(ObjFile))
return ELFObj->getELFFile()->getRelativeRelocationType();
else
return static_cast<uint32_t>(0);
@@ -108,11 +116,21 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
for (const object::SectionRef &Section : Sections) {
for (const object::RelocationRef &Reloc : Section.relocations()) {
- if (SupportsRelocation && SupportsRelocation(Reloc.getType())) {
+ if (ObjFile.getBinary()->getArch() == Triple::arm) {
+ if (SupportsRelocation && SupportsRelocation(Reloc.getType())) {
+ Expected<uint64_t> ValueOrErr = Reloc.getSymbol()->getValue();
+ if (!ValueOrErr)
+ return ValueOrErr.takeError();
+ Relocs.insert({Reloc.getOffset(), Resolver(Reloc, *ValueOrErr, 0)});
+ }
+ } else if (SupportsRelocation && SupportsRelocation(Reloc.getType())) {
auto AddendOrErr = object::ELFRelocationRef(Reloc).getAddend();
auto A = AddendOrErr ? *AddendOrErr : 0;
- uint64_t resolved = Resolver(Reloc, Reloc.getSymbol()->getValue(), A);
- Relocs.insert({Reloc.getOffset(), resolved});
+ Expected<uint64_t> ValueOrErr = Reloc.getSymbol()->getValue();
+ if (!ValueOrErr)
+ // TODO: Test this error.
+ return ValueOrErr.takeError();
+ Relocs.insert({Reloc.getOffset(), Resolver(Reloc, *ValueOrErr, A)});
} else if (Reloc.getType() == RelativeRelocation) {
if (auto AddendOrErr = object::ELFRelocationRef(Reloc).getAddend())
Relocs.insert({Reloc.getOffset(), *AddendOrErr});
@@ -123,12 +141,13 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
// Copy the instrumentation map data into the Sleds data structure.
auto C = Contents.bytes_begin();
- static constexpr size_t ELF64SledEntrySize = 32;
+ bool Is32Bit = ObjFile.getBinary()->makeTriple().isArch32Bit();
+ size_t ELFSledEntrySize = Is32Bit ? 16 : 32;
- if ((C - Contents.bytes_end()) % ELF64SledEntrySize != 0)
+ if ((C - Contents.bytes_end()) % ELFSledEntrySize != 0)
return make_error<StringError>(
Twine("Instrumentation map entries not evenly divisible by size of "
- "an XRay sled entry in ELF64."),
+ "an XRay sled entry."),
std::make_error_code(std::errc::executable_format_error));
auto RelocateOrElse = [&](uint64_t Offset, uint64_t Address) {
@@ -141,19 +160,26 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
return Address;
};
+ const int WordSize = Is32Bit ? 4 : 8;
int32_t FuncId = 1;
uint64_t CurFn = 0;
- for (; C != Contents.bytes_end(); C += ELF64SledEntrySize) {
+ for (; C != Contents.bytes_end(); C += ELFSledEntrySize) {
DataExtractor Extractor(
- StringRef(reinterpret_cast<const char *>(C), ELF64SledEntrySize), true,
+ StringRef(reinterpret_cast<const char *>(C), ELFSledEntrySize), true,
8);
Sleds.push_back({});
auto &Entry = Sleds.back();
uint64_t OffsetPtr = 0;
uint64_t AddrOff = OffsetPtr;
- Entry.Address = RelocateOrElse(AddrOff, Extractor.getU64(&OffsetPtr));
+ if (Is32Bit)
+ Entry.Address = RelocateOrElse(AddrOff, Extractor.getU32(&OffsetPtr));
+ else
+ Entry.Address = RelocateOrElse(AddrOff, Extractor.getU64(&OffsetPtr));
uint64_t FuncOff = OffsetPtr;
- Entry.Function = RelocateOrElse(FuncOff, Extractor.getU64(&OffsetPtr));
+ if (Is32Bit)
+ Entry.Function = RelocateOrElse(FuncOff, Extractor.getU32(&OffsetPtr));
+ else
+ Entry.Function = RelocateOrElse(FuncOff, Extractor.getU64(&OffsetPtr));
auto Kind = Extractor.getU8(&OffsetPtr);
static constexpr SledEntry::FunctionKinds Kinds[] = {
SledEntry::FunctionKinds::ENTRY, SledEntry::FunctionKinds::EXIT,
@@ -165,6 +191,11 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
std::make_error_code(std::errc::executable_format_error));
Entry.Kind = Kinds[Kind];
Entry.AlwaysInstrument = Extractor.getU8(&OffsetPtr) != 0;
+ Entry.Version = Extractor.getU8(&OffsetPtr);
+ if (Entry.Version >= 2) {
+ Entry.Address += C - Contents.bytes_begin() + Address;
+ Entry.Function += C - Contents.bytes_begin() + WordSize + Address;
+ }
// We do replicate the function id generation scheme implemented in the
// XRay runtime.
@@ -209,8 +240,8 @@ loadYAML(sys::fs::file_t Fd, size_t FileSize, StringRef Filename,
for (const auto &Y : YAMLSleds) {
FunctionAddresses[Y.FuncId] = Y.Function;
FunctionIds[Y.Function] = Y.FuncId;
- Sleds.push_back(
- SledEntry{Y.Address, Y.Function, Y.Kind, Y.AlwaysInstrument});
+ Sleds.push_back(SledEntry{Y.Address, Y.Function, Y.Kind, Y.AlwaysInstrument,
+ Y.Version});
}
return Error::success();
}
@@ -228,7 +259,8 @@ llvm::xray::loadInstrumentationMap(StringRef Filename) {
if (!ObjectFileOrError) {
auto E = ObjectFileOrError.takeError();
// We try to load it as YAML if the ELF load didn't work.
- Expected<sys::fs::file_t> FdOrErr = sys::fs::openNativeFileForRead(Filename);
+ Expected<sys::fs::file_t> FdOrErr =
+ sys::fs::openNativeFileForRead(Filename);
if (!FdOrErr) {
// Report the ELF load error if YAML failed.
consumeError(FdOrErr.takeError());
@@ -250,7 +282,7 @@ llvm::xray::loadInstrumentationMap(StringRef Filename) {
Map.FunctionAddresses, Map.FunctionIds))
return std::move(E);
} else if (auto E = loadObj(Filename, *ObjectFileOrError, Map.Sleds,
- Map.FunctionAddresses, Map.FunctionIds)) {
+ Map.FunctionAddresses, Map.FunctionIds)) {
return std::move(E);
}
return Map;
diff --git a/llvm/lib/XRay/Trace.cpp b/llvm/lib/XRay/Trace.cpp
index 4f107e1059cc..5ceb269b6d1d 100644
--- a/llvm/lib/XRay/Trace.cpp
+++ b/llvm/lib/XRay/Trace.cpp
@@ -410,6 +410,7 @@ Expected<Trace> llvm::xray::loadTraceFile(StringRef Filename, bool Sort) {
auto TraceOrError = loadTrace(LittleEndianDE, Sort);
if (!TraceOrError) {
DataExtractor BigEndianDE(Data, false, 8);
+ consumeError(TraceOrError.takeError());
TraceOrError = loadTrace(BigEndianDE, Sort);
}
return TraceOrError;