diff options
Diffstat (limited to 'llvm/lib/XRay/FDRTraceWriter.cpp')
| -rw-r--r-- | llvm/lib/XRay/FDRTraceWriter.cpp | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/llvm/lib/XRay/FDRTraceWriter.cpp b/llvm/lib/XRay/FDRTraceWriter.cpp index b9b71eb14a8..c68e915bbb5 100644 --- a/llvm/lib/XRay/FDRTraceWriter.cpp +++ b/llvm/lib/XRay/FDRTraceWriter.cpp @@ -39,19 +39,16 @@ struct FunctionDeltaBlob { uint32_t TSCDelta; }; -template <size_t Index> struct IndexedMemcpy { +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> - static void Copy(char *Dest, Tuple &&T) { - auto Next = static_cast<char *>(std::memcpy( - Dest, reinterpret_cast<const char *>(&std::get<Index>(T)), - sizeof(std::get<Index>(T)))) + - sizeof(std::get<Index>(T)); - IndexedMemcpy<Index + 1>::Copy(Next, T); + 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); } template < @@ -60,34 +57,43 @@ template <size_t Index> struct IndexedMemcpy { (Index >= std::tuple_size<typename std::remove_reference<Tuple>::type>::value), int>::type = 0> - static void Copy(char *, Tuple &&) {} + static size_t write(support::endian::Writer &OS, Tuple &&) { + return 0; + } }; template <uint8_t Kind, class... Values> -Error writeMetadata(raw_ostream &OS, Values &&... Ds) { - MetadataBlob B; - B.Type = 1; - B.RecordKind = Kind; - std::memset(B.Data, 0, 15); +Error writeMetadata(support::endian::Writer &OS, Values &&... Ds) { + uint8_t FirstByte = (Kind << 1) | uint8_t{0x01}; auto T = std::make_tuple(std::forward<Values>(std::move(Ds))...); - IndexedMemcpy<0>::Copy(B.Data, T); - OS.write(reinterpret_cast<const char *>(&B), sizeof(MetadataBlob)); + // Write in field order. + OS.write(FirstByte); + auto Bytes = IndexedWriter<0>::write(OS, T); + assert(Bytes <= 15 && "Must only ever write at most 16 byte metadata!"); + // Pad out with appropriate numbers of zero's. + for (; Bytes < 15; ++Bytes) + OS.write('\0'); return Error::success(); } } // namespace FDRTraceWriter::FDRTraceWriter(raw_ostream &O, const XRayFileHeader &H) - : OS(O) { + : OS(O, support::endianness::native) { // We need to re-construct a header, by writing the fields we care about for // traces, in the format that the runtime would have written. - FileHeader Raw; - Raw.Version = H.Version; - Raw.Type = H.Type; - Raw.BitField = (H.ConstantTSC ? 0x01 : 0x0) | (H.NonstopTSC ? 0x02 : 0x0); - Raw.CycleFrequency = H.CycleFrequency; - memcpy(&Raw.FreeForm, H.FreeFormData, 16); - OS.write(reinterpret_cast<const char *>(&Raw), sizeof(XRayFileHeader)); + uint32_t BitField = + (H.ConstantTSC ? 0x01 : 0x0) | (H.NonstopTSC ? 0x02 : 0x0); + + // For endian-correctness, we need to write these fields in the order they + // appear and that we expect, instead of blasting bytes of the struct through. + OS.write(H.Version); + OS.write(H.Type); + OS.write(BitField); + OS.write(H.CycleFrequency); + ArrayRef<char> FreeFormBytes(H.FreeFormData, + sizeof(XRayFileHeader::FreeFormData)); + OS.write(FreeFormBytes); } FDRTraceWriter::~FDRTraceWriter() {} @@ -111,7 +117,8 @@ Error FDRTraceWriter::visit(TSCWrapRecord &R) { Error FDRTraceWriter::visit(CustomEventRecord &R) { if (auto E = writeMetadata<5u>(OS, R.size(), R.tsc())) return E; - OS.write(R.data().data(), R.data().size()); + ArrayRef<char> Bytes(R.data().data(), R.data().size()); + OS.write(Bytes); return Error::success(); } @@ -137,7 +144,9 @@ Error FDRTraceWriter::visit(FunctionRecord &R) { B.RecordKind = static_cast<uint8_t>(R.recordType()); B.FuncId = R.functionId(); B.TSCDelta = R.delta(); - OS.write(reinterpret_cast<const char *>(&B), sizeof(FunctionDeltaBlob)); + ArrayRef<char> Bytes(reinterpret_cast<const char *>(&B), + sizeof(FunctionDeltaBlob)); + OS.write(Bytes); return Error::success(); } |

