diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /llvm/lib/XRay | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) | |
download | src-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.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/XRay/FDRTraceWriter.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/XRay/InstrumentationMap.cpp | 76 | ||||
-rw-r--r-- | llvm/lib/XRay/Trace.cpp | 1 |
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; |