LLVM: lib/XRay/RecordInitializer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

9

10using namespace llvm;

12

14 if (!E.isValidOffsetForDataOfSize(OffsetPtr, sizeof(uint64_t)))

16 std::make_error_code(std::errc::bad_address),

17 "Invalid offset for a buffer extent (%" PRId64 ").", OffsetPtr);

18

19 auto PreReadOffset = OffsetPtr;

20 R.Size = E.getU64(&OffsetPtr);

21 if (PreReadOffset == OffsetPtr)

22 return createStringError(std::make_error_code(std::errc::invalid_argument),

23 "Cannot read buffer extent at offset %" PRId64 ".",

24 OffsetPtr);

25

28}

29

31 if (!E.isValidOffsetForDataOfSize(OffsetPtr,

34 std::make_error_code(std::errc::bad_address),

35 "Invalid offset for a wallclock record (%" PRId64 ").", OffsetPtr);

36 auto BeginOffset = OffsetPtr;

37 auto PreReadOffset = OffsetPtr;

38 R.Seconds = E.getU64(&OffsetPtr);

39 if (OffsetPtr == PreReadOffset)

41 std::make_error_code(std::errc::invalid_argument),

42 "Cannot read wall clock 'seconds' field at offset %" PRId64 ".",

43 OffsetPtr);

44

45 PreReadOffset = OffsetPtr;

46 R.Nanos = E.getU32(&OffsetPtr);

47 if (OffsetPtr == PreReadOffset)

49 std::make_error_code(std::errc::invalid_argument),

50 "Cannot read wall clock 'nanos' field at offset %" PRId64 ".",

51 OffsetPtr);

52

53

57}

58

60 if (!E.isValidOffsetForDataOfSize(OffsetPtr,

63 std::make_error_code(std::errc::bad_address),

64 "Invalid offset for a new cpu id record (%" PRId64 ").", OffsetPtr);

65 auto BeginOffset = OffsetPtr;

66 auto PreReadOffset = OffsetPtr;

67 R.CPUId = E.getU16(&OffsetPtr);

68 if (OffsetPtr == PreReadOffset)

69 return createStringError(std::make_error_code(std::errc::invalid_argument),

70 "Cannot read CPU id at offset %" PRId64 ".",

71 OffsetPtr);

72

73 PreReadOffset = OffsetPtr;

74 R.TSC = E.getU64(&OffsetPtr);

75 if (OffsetPtr == PreReadOffset)

76 return createStringError(std::make_error_code(std::errc::invalid_argument),

77 "Cannot read CPU TSC at offset %" PRId64 ".",

78 OffsetPtr);

79

82}

83

85 if (!E.isValidOffsetForDataOfSize(OffsetPtr,

88 std::make_error_code(std::errc::bad_address),

89 "Invalid offset for a new TSC wrap record (%" PRId64 ").", OffsetPtr);

90

91 auto PreReadOffset = OffsetPtr;

92 R.BaseTSC = E.getU64(&OffsetPtr);

93 if (PreReadOffset == OffsetPtr)

95 std::make_error_code(std::errc::invalid_argument),

96 "Cannot read TSC wrap record at offset %" PRId64 ".", OffsetPtr);

97

100}

101

103 if (!E.isValidOffsetForDataOfSize(OffsetPtr,

106 std::make_error_code(std::errc::bad_address),

107 "Invalid offset for a custom event record (%" PRId64 ").", OffsetPtr);

108

109 auto BeginOffset = OffsetPtr;

110 auto PreReadOffset = OffsetPtr;

111 R.Size = E.getSigned(&OffsetPtr, sizeof(int32_t));

112 if (PreReadOffset == OffsetPtr)

114 std::make_error_code(std::errc::invalid_argument),

115 "Cannot read a custom event record size field offset %" PRId64 ".",

116 OffsetPtr);

117

118 if (R.Size <= 0)

120 std::make_error_code(std::errc::bad_address),

121 "Invalid size for custom event (size = %d) at offset %" PRId64 ".",

122 R.Size, OffsetPtr);

123

124 PreReadOffset = OffsetPtr;

125 R.TSC = E.getU64(&OffsetPtr);

126 if (PreReadOffset == OffsetPtr)

128 std::make_error_code(std::errc::invalid_argument),

129 "Cannot read a custom event TSC field at offset %" PRId64 ".",

130 OffsetPtr);

131

132

133

134 if (Version >= 4) {

135 PreReadOffset = OffsetPtr;

136 R.CPU = E.getU16(&OffsetPtr);

137 if (PreReadOffset == OffsetPtr)

139 std::make_error_code(std::errc::invalid_argument),

140 "Missing CPU field at offset %" PRId64 ".", OffsetPtr);

141 }

142

143 assert(OffsetPtr > BeginOffset &&

146

147

148 if (!E.isValidOffsetForDataOfSize(OffsetPtr, R.Size))

150 std::make_error_code(std::errc::bad_address),

151 "Cannot read %d bytes of custom event data from offset %" PRId64 ".",

152 R.Size, OffsetPtr);

153

154 std::vector<uint8_t> Buffer;

155 Buffer.resize(R.Size);

156 PreReadOffset = OffsetPtr;

157 if (E.getU8(&OffsetPtr, Buffer.data(), R.Size) != Buffer.data())

159 std::make_error_code(std::errc::invalid_argument),

160 "Failed reading data into buffer of size %d at offset %" PRId64 ".",

161 R.Size, OffsetPtr);

162

163 assert(OffsetPtr >= PreReadOffset);

164 if (OffsetPtr - PreReadOffset != static_cast<uint32_t>(R.Size))

166 std::make_error_code(std::errc::invalid_argument),

167 "Failed reading enough bytes for the custom event payload -- read "

168 "%" PRId64 " expecting %d bytes at offset %" PRId64 ".",

169 OffsetPtr - PreReadOffset, R.Size, PreReadOffset);

170

171 R.Data.assign(Buffer.begin(), Buffer.end());

173}

174

176 if (!E.isValidOffsetForDataOfSize(OffsetPtr,

179 std::make_error_code(std::errc::bad_address),

180 "Invalid offset for a custom event record (%" PRId64 ").", OffsetPtr);

181

182 auto BeginOffset = OffsetPtr;

183 auto PreReadOffset = OffsetPtr;

184

185 R.Size = E.getSigned(&OffsetPtr, sizeof(int32_t));

186 if (PreReadOffset == OffsetPtr)

188 std::make_error_code(std::errc::invalid_argument),

189 "Cannot read a custom event record size field offset %" PRId64 ".",

190 OffsetPtr);

191

192 if (R.Size <= 0)

194 std::make_error_code(std::errc::bad_address),

195 "Invalid size for custom event (size = %d) at offset %" PRId64 ".",

196 R.Size, OffsetPtr);

197

198 PreReadOffset = OffsetPtr;

199 R.Delta = E.getSigned(&OffsetPtr, sizeof(int32_t));

200 if (PreReadOffset == OffsetPtr)

202 std::make_error_code(std::errc::invalid_argument),

203 "Cannot read a custom event record TSC delta field at offset "

204 "%" PRId64 ".",

205 OffsetPtr);

206

207 assert(OffsetPtr > BeginOffset &&

210

211

212 if (!E.isValidOffsetForDataOfSize(OffsetPtr, R.Size))

214 std::make_error_code(std::errc::bad_address),

215 "Cannot read %d bytes of custom event data from offset %" PRId64 ".",

216 R.Size, OffsetPtr);

217

218 std::vector<uint8_t> Buffer;

219 Buffer.resize(R.Size);

220 PreReadOffset = OffsetPtr;

221 if (E.getU8(&OffsetPtr, Buffer.data(), R.Size) != Buffer.data())

223 std::make_error_code(std::errc::invalid_argument),

224 "Failed reading data into buffer of size %d at offset %" PRId64 ".",

225 R.Size, OffsetPtr);

226

227 assert(OffsetPtr >= PreReadOffset);

228 if (OffsetPtr - PreReadOffset != static_cast<uint32_t>(R.Size))

230 std::make_error_code(std::errc::invalid_argument),

231 "Failed reading enough bytes for the custom event payload -- read "

232 "%" PRId64 " expecting %d bytes at offset %" PRId64 ".",

233 OffsetPtr - PreReadOffset, R.Size, PreReadOffset);

234

235 R.Data.assign(Buffer.begin(), Buffer.end());

237}

238

240 if (!E.isValidOffsetForDataOfSize(OffsetPtr,

243 std::make_error_code(std::errc::bad_address),

244 "Invalid offset for a typed event record (%" PRId64 ").", OffsetPtr);

245

246 auto BeginOffset = OffsetPtr;

247 auto PreReadOffset = OffsetPtr;

248

249 R.Size = E.getSigned(&OffsetPtr, sizeof(int32_t));

250 if (PreReadOffset == OffsetPtr)

252 std::make_error_code(std::errc::invalid_argument),

253 "Cannot read a typed event record size field offset %" PRId64 ".",

254 OffsetPtr);

255

256 if (R.Size <= 0)

258 std::make_error_code(std::errc::bad_address),

259 "Invalid size for typed event (size = %d) at offset %" PRId64 ".",

260 R.Size, OffsetPtr);

261

262 PreReadOffset = OffsetPtr;

263 R.Delta = E.getSigned(&OffsetPtr, sizeof(int32_t));

264 if (PreReadOffset == OffsetPtr)

266 std::make_error_code(std::errc::invalid_argument),

267 "Cannot read a typed event record TSC delta field at offset "

268 "%" PRId64 ".",

269 OffsetPtr);

270

271 PreReadOffset = OffsetPtr;

272 R.EventType = E.getU16(&OffsetPtr);

273 if (PreReadOffset == OffsetPtr)

275 std::make_error_code(std::errc::invalid_argument),

276 "Cannot read a typed event record type field at offset %" PRId64 ".",

277 OffsetPtr);

278

279 assert(OffsetPtr > BeginOffset &&

282

283

284 if (!E.isValidOffsetForDataOfSize(OffsetPtr, R.Size))

286 std::make_error_code(std::errc::bad_address),

287 "Cannot read %d bytes of custom event data from offset %" PRId64 ".",

288 R.Size, OffsetPtr);

289

290 std::vector<uint8_t> Buffer;

291 Buffer.resize(R.Size);

292 PreReadOffset = OffsetPtr;

293 if (E.getU8(&OffsetPtr, Buffer.data(), R.Size) != Buffer.data())

295 std::make_error_code(std::errc::invalid_argument),

296 "Failed reading data into buffer of size %d at offset %" PRId64 ".",

297 R.Size, OffsetPtr);

298

299 assert(OffsetPtr >= PreReadOffset);

300 if (OffsetPtr - PreReadOffset != static_cast<uint32_t>(R.Size))

302 std::make_error_code(std::errc::invalid_argument),

303 "Failed reading enough bytes for the typed event payload -- read "

304 "%" PRId64 " expecting %d bytes at offset %" PRId64 ".",

305 OffsetPtr - PreReadOffset, R.Size, PreReadOffset);

306

307 R.Data.assign(Buffer.begin(), Buffer.end());

309}

310

312 if (!E.isValidOffsetForDataOfSize(OffsetPtr,

315 std::make_error_code(std::errc::bad_address),

316 "Invalid offset for a call argument record (%" PRId64 ").",

317 OffsetPtr);

318

319 auto PreReadOffset = OffsetPtr;

320 R.Arg = E.getU64(&OffsetPtr);

321 if (PreReadOffset == OffsetPtr)

323 std::make_error_code(std::errc::invalid_argument),

324 "Cannot read a call arg record at offset %" PRId64 ".", OffsetPtr);

325

328}

329

331 if (!E.isValidOffsetForDataOfSize(OffsetPtr,

334 std::make_error_code(std::errc::bad_address),

335 "Invalid offset for a process ID record (%" PRId64 ").", OffsetPtr);

336

337 auto PreReadOffset = OffsetPtr;

338 R.PID = E.getSigned(&OffsetPtr, 4);

339 if (PreReadOffset == OffsetPtr)

341 std::make_error_code(std::errc::invalid_argument),

342 "Cannot read a process ID record at offset %" PRId64 ".", OffsetPtr);

343

346}

347

349 if (!E.isValidOffsetForDataOfSize(OffsetPtr,

352 std::make_error_code(std::errc::bad_address),

353 "Invalid offset for a new buffer record (%" PRId64 ").", OffsetPtr);

354

355 auto PreReadOffset = OffsetPtr;

356 R.TID = E.getSigned(&OffsetPtr, sizeof(int32_t));

357 if (PreReadOffset == OffsetPtr)

359 std::make_error_code(std::errc::invalid_argument),

360 "Cannot read a new buffer record at offset %" PRId64 ".", OffsetPtr);

361

364}

365

367 if (!E.isValidOffsetForDataOfSize(OffsetPtr,

370 std::make_error_code(std::errc::bad_address),

371 "Invalid offset for an end-of-buffer record (%" PRId64 ").",

372 OffsetPtr);

373

376}

377

379

380

381

382

383

384

385

386

387 if (OffsetPtr == 0 || !E.isValidOffsetForDataOfSize(

388 --OffsetPtr, FunctionRecord::kFunctionRecordSize))

390 std::make_error_code(std::errc::bad_address),

391 "Invalid offset for a function record (%" PRId64 ").", OffsetPtr);

392

393 auto BeginOffset = OffsetPtr;

394 auto PreReadOffset = BeginOffset;

395 uint32_t Buffer = E.getU32(&OffsetPtr);

396 if (PreReadOffset == OffsetPtr)

398 std::make_error_code(std::errc::bad_address),

399 "Cannot read function id field from offset %" PRId64 ".", OffsetPtr);

400

401

402

403

404 unsigned FunctionType = (Buffer >> 1) & 0x07u;

411 break;

412 default:

414 std::make_error_code(std::errc::invalid_argument),

415 "Unknown function record type '%d' at offset %" PRId64 ".",

417 }

418

419 R.FuncId = Buffer >> 4;

420 PreReadOffset = OffsetPtr;

421 R.Delta = E.getU32(&OffsetPtr);

422 if (OffsetPtr == PreReadOffset)

424 std::make_error_code(std::errc::invalid_argument),

425 "Failed reading TSC delta from offset %" PRId64 ".", OffsetPtr);

426 assert(FunctionRecord::kFunctionRecordSize == (OffsetPtr - BeginOffset));

428}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Class to represent function types.

Error visit(BufferExtents &) override

Definition RecordInitializer.cpp:13

RecordTypes

Determines the supported types of records that could be seen in XRay traces.

This is an optimization pass for GlobalISel generic memory operations.

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.