1 //===- FDRRecordProducer.cpp - XRay FDR Mode Record Producer --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 #include "llvm/XRay/FDRRecordProducer.h"
10 #include "llvm/Support/DataExtractor.h"
17 Expected
<std::unique_ptr
<Record
>>
18 metadataRecordType(const XRayFileHeader
&Header
, uint8_t T
) {
19 // Keep this in sync with the values written in the XRay FDR mode runtime in
21 enum MetadataRecordKinds
: uint8_t {
27 CustomEventMarkerKind
,
32 // This is an end marker, used to identify the upper bound for this enum.
36 if (T
>= static_cast<uint8_t>(MetadataRecordKinds::EnumEndMarker
))
37 return createStringError(std::make_error_code(std::errc::invalid_argument
),
38 "Invalid metadata record type: %d", T
);
40 case MetadataRecordKinds::NewBufferKind
:
41 return make_unique
<NewBufferRecord
>();
42 case MetadataRecordKinds::EndOfBufferKind
:
43 if (Header
.Version
>= 2)
44 return createStringError(
45 std::make_error_code(std::errc::executable_format_error
),
46 "End of buffer records are no longer supported starting version "
48 return make_unique
<EndBufferRecord
>();
49 case MetadataRecordKinds::NewCPUIdKind
:
50 return make_unique
<NewCPUIDRecord
>();
51 case MetadataRecordKinds::TSCWrapKind
:
52 return make_unique
<TSCWrapRecord
>();
53 case MetadataRecordKinds::WalltimeMarkerKind
:
54 return make_unique
<WallclockRecord
>();
55 case MetadataRecordKinds::CustomEventMarkerKind
:
56 return make_unique
<CustomEventRecord
>();
57 case MetadataRecordKinds::CallArgumentKind
:
58 return make_unique
<CallArgRecord
>();
59 case MetadataRecordKinds::BufferExtentsKind
:
60 return make_unique
<BufferExtents
>();
61 case MetadataRecordKinds::TypedEventMarkerKind
:
62 return createStringError(std::make_error_code(std::errc::invalid_argument
),
63 "Encountered an unsupported TypedEventMarker.");
64 case MetadataRecordKinds::PidKind
:
65 return make_unique
<PIDRecord
>();
66 case MetadataRecordKinds::EnumEndMarker
:
67 llvm_unreachable("Invalid MetadataRecordKind");
69 llvm_unreachable("Unhandled MetadataRecordKinds enum value");
74 Expected
<std::unique_ptr
<Record
>> FileBasedRecordProducer::produce() {
75 // At the top level, we read one byte to determine the type of the record to
76 // create. This byte will comprise of the following bits:
78 // - offset 0: A '1' indicates a metadata record, a '0' indicates a function
80 // - offsets 1-7: For metadata records, this will indicate the kind of
81 // metadata record should be loaded.
83 // We read first byte, then create the appropriate type of record to consume
84 // the rest of the bytes.
85 auto PreReadOffset
= OffsetPtr
;
86 uint8_t FirstByte
= E
.getU8(&OffsetPtr
);
87 std::unique_ptr
<Record
> R
;
89 // For metadata records, handle especially here.
90 if (FirstByte
& 0x01) {
91 auto LoadedType
= FirstByte
>> 1;
92 auto MetadataRecordOrErr
= metadataRecordType(Header
, LoadedType
);
93 if (!MetadataRecordOrErr
)
95 MetadataRecordOrErr
.takeError(),
97 std::make_error_code(std::errc::executable_format_error
),
98 "Encountered an unsupported metadata record (%d) at offset %d.",
99 LoadedType
, PreReadOffset
));
100 R
= std::move(MetadataRecordOrErr
.get());
102 R
= llvm::make_unique
<FunctionRecord
>();
104 RecordInitializer
RI(E
, OffsetPtr
);
106 if (auto Err
= R
->apply(RI
))
107 return std::move(Err
);
109 assert(R
!= nullptr);