LLVM: lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

10

22

23using namespace llvm;

27

29 : Msf(Msf), Allocator(Msf.getAllocator()), Age(1), BuildNumber(0),

30 PdbDllVersion(0), PdbDllRbld(0), Flags(0), MachineType(PDB_Machine::x86),

31 Header(nullptr) {}

32

34

36

38

40

48

50

52

54

56

58

59 MachineType = static_cast<pdb::PDB_Machine>(static_cast<unsigned>(M));

60}

61

63 GlobalsStreamIndex = Index;

64}

65

67 SymRecordStreamIndex = Index;

68}

69

71 PublicsStreamIndex = Index;

72}

73

75 if (!NewFpoData)

76 NewFpoData.emplace(false);

77

78 NewFpoData->addFrameData(FD);

79}

80

82 OldFpoData.push_back(FD);

83}

84

88 "NewFPO data should be written via addFrameData()!");

89

90 DbgStreams[(int)Type] = DebugStream{};

94 };

96}

97

99 return ECNamesBuilder.insert(Name);

100}

101

103

104 return sizeof(DbiStreamHeader) + calculateFileInfoSubstreamSize() +

105 calculateModiSubstreamSize() + calculateSectionContribsStreamSize() +

106 calculateSectionMapStreamSize() + calculateDbgStreamsSize() +

107 ECNamesBuilder.calculateSerializedSize();

108}

109

112 uint32_t Index = ModiList.size();

113 ModiList.push_back(

114 std::make_unique(ModuleName, Index, Msf));

115 return *ModiList.back();

116}

117

120 uint32_t Index = SourceFileNames.size();

121 SourceFileNames.insert(std::make_pair(File, Index));

122 Module.addSourceFile(File);

124}

125

127 auto NameIter = SourceFileNames.find(File);

128 if (NameIter == SourceFileNames.end())

130 "The specified source file was not found");

131 return NameIter->getValue();

132}

133

134uint32_t DbiStreamBuilder::calculateModiSubstreamSize() const {

136 for (const auto &M : ModiList)

137 Size += M->calculateSerializedLength();

139}

140

141uint32_t DbiStreamBuilder::calculateSectionContribsStreamSize() const {

143 return 0;

146}

147

148uint32_t DbiStreamBuilder::calculateSectionMapStreamSize() const {

149 if (SectionMap.empty())

150 return 0;

152}

153

154uint32_t DbiStreamBuilder::calculateNamesOffset() const {

159 Offset += ModiList.size() * sizeof(ulittle16_t);

160 uint32_t NumFileInfos = 0;

161 for (const auto &M : ModiList)

162 NumFileInfos += M->source_files().size();

165}

166

167uint32_t DbiStreamBuilder::calculateFileInfoSubstreamSize() const {

168 uint32_t Size = calculateNamesOffset();

169 Size += calculateNamesBufferSize();

171}

172

173uint32_t DbiStreamBuilder::calculateNamesBufferSize() const {

174 uint32_t Size = 0;

175 for (const auto &F : SourceFileNames) {

176 Size += F.getKeyLength() + 1;

177 }

179}

180

181uint32_t DbiStreamBuilder::calculateDbgStreamsSize() const {

182 return DbgStreams.size() * sizeof(uint16_t);

183}

184

185Error DbiStreamBuilder::generateFileInfoSubstream() {

186 uint32_t Size = calculateFileInfoSubstreamSize();

187 auto Data = Allocator.Allocate<uint8_t>(Size);

188 uint32_t NamesOffset = calculateNamesOffset();

189

190 FileInfoBuffer = MutableBinaryByteStream(MutableArrayRef<uint8_t>(Data, Size),

192

193 WritableBinaryStreamRef MetadataBuffer =

194 WritableBinaryStreamRef(FileInfoBuffer).keep_front(NamesOffset);

195 BinaryStreamWriter MetadataWriter(MetadataBuffer);

196

197 uint16_t ModiCount = std::min<uint32_t>(UINT16_MAX, ModiList.size());

198 uint16_t FileCount = std::min<uint32_t>(UINT16_MAX, SourceFileNames.size());

199 if (auto EC = MetadataWriter.writeInteger(ModiCount))

200 return EC;

201 if (auto EC = MetadataWriter.writeInteger(FileCount))

202 return EC;

203 for (uint16_t I = 0; I < ModiCount; ++I) {

204 if (auto EC = MetadataWriter.writeInteger(I))

205 return EC;

206 }

207 for (const auto &MI : ModiList) {

208 FileCount = static_cast<uint16_t>(MI->source_files().size());

209 if (auto EC = MetadataWriter.writeInteger(FileCount))

210 return EC;

211 }

212

213

214

215

216

217 NamesBuffer = WritableBinaryStreamRef(FileInfoBuffer).drop_front(NamesOffset);

218 BinaryStreamWriter NameBufferWriter(NamesBuffer);

219 for (auto &Name : SourceFileNames) {

220 Name.second = NameBufferWriter.getOffset();

221 if (auto EC = NameBufferWriter.writeCString(Name.getKey()))

222 return EC;

223 }

224

225 for (const auto &MI : ModiList) {

226 for (StringRef Name : MI->source_files()) {

227 auto Result = SourceFileNames.find(Name);

228 if (Result == SourceFileNames.end())

230 "The source file was not found.");

231 if (auto EC = MetadataWriter.writeInteger(Result->second))

232 return EC;

233 }

234 }

235

236 if (auto EC = NameBufferWriter.padToAlignment(sizeof(uint32_t)))

237 return EC;

238

239 if (NameBufferWriter.bytesRemaining() > 0)

241 "The names buffer contained unexpected data.");

242

243 if (MetadataWriter.bytesRemaining() > sizeof(uint32_t))

246 "The metadata buffer contained unexpected data.");

247

249}

250

251Error DbiStreamBuilder::finalize() {

252 if (Header)

254

255 for (auto &MI : ModiList)

256 MI->finalize();

257

258 if (auto EC = generateFileInfoSubstream())

259 return EC;

260

261 DbiStreamHeader *H = Allocator.Allocate();

262 ::memset(H, 0, sizeof(DbiStreamHeader));

263 H->VersionHeader = *VerHeader;

264 H->VersionSignature = -1;

265 H->Age = Age;

266 H->BuildNumber = BuildNumber;

267 H->Flags = Flags;

268 H->PdbDllRbld = PdbDllRbld;

269 H->PdbDllVersion = PdbDllVersion;

270 H->MachineType = static_cast<uint16_t>(MachineType);

271

272 H->ECSubstreamSize = ECNamesBuilder.calculateSerializedSize();

273 H->FileInfoSize = FileInfoBuffer.getLength();

274 H->ModiSubstreamSize = calculateModiSubstreamSize();

275 H->OptionalDbgHdrSize = DbgStreams.size() * sizeof(uint16_t);

276 H->SecContrSubstreamSize = calculateSectionContribsStreamSize();

277 H->SectionMapSize = calculateSectionMapStreamSize();

278 H->TypeServerSize = 0;

279 H->SymRecordStreamIndex = SymRecordStreamIndex;

280 H->PublicSymbolStreamIndex = PublicsStreamIndex;

281 H->MFCTypeServerIndex = 0;

282 H->GlobalSymbolStreamIndex = GlobalsStreamIndex;

283

284 Header = H;

286}

287

289 if (NewFpoData) {

292 NewFpoData->calculateSerializedSize();

295 return NewFpoData->commit(Writer);

296 };

297 }

298

299 if (!OldFpoData.empty()) {

306 };

307 }

308

309 for (auto &S : DbgStreams) {

310 if (!S)

311 continue;

312 auto ExpectedIndex = Msf.addStream(S->Size);

313 if (!ExpectedIndex)

314 return ExpectedIndex.takeError();

315 S->StreamNumber = *ExpectedIndex;

316 }

317

318 for (auto &MI : ModiList) {

319 if (auto EC = MI->finalizeMsfLayout())

320 return EC;

321 }

322

325 return EC;

327}

328

339

340

342

343 return Ret;

344}

345

346

347

348

349

350

353 int Idx = 0;

354

356 SectionMap.emplace_back();

357 auto &Entry = SectionMap.back();

358 memset(&Entry, 0, sizeof(Entry));

359

360 Entry.Frame = Idx + 1;

361

362

363 Entry.SecName = UINT16_MAX;

364 Entry.ClassName = UINT16_MAX;

365

366 return Entry;

367 };

368

369 for (auto &Hdr : SecHdrs) {

370 auto &Entry = Add();

371 Entry.Flags = toSecMapFlags(Hdr.Characteristics);

372 Entry.SecByteLength = Hdr.VirtualSize;

373 ++Idx;

374 }

375

376

377 auto &Entry = Add();

380 Entry.SecByteLength = UINT32_MAX;

381}

382

387 return EC;

388

390 Layout, MsfBuffer, StreamDBI, Allocator);

391

394 return EC;

395

396 for (auto &M : ModiList) {

397 if (auto EC = M->commit(Writer))

398 return EC;

399 }

400

401

403 ModiList, [&](std::unique_ptr &M) {

404 return M->commitSymbolStream(Layout, MsfBuffer);

405 }))

406 return EC;

407

408 if (!SectionContribs.empty()) {

410 return EC;

412 return EC;

413 }

414

415 if (!SectionMap.empty()) {

419 return EC;

421 return EC;

422 }

423

425 return EC;

426

427 if (auto EC = ECNamesBuilder.commit(Writer))

428 return EC;

429

430 for (auto &Stream : DbgStreams) {

432 if (Stream)

433 StreamNumber = Stream->StreamNumber;

435 return EC;

436 }

437

438 for (auto &Stream : DbgStreams) {

439 if (!Stream)

440 continue;

442

444 Layout, MsfBuffer, Stream->StreamNumber, Allocator);

446

447 if (auto EC = Stream->WriteFn(DbgStreamWriter))

448 return EC;

449 }

450

453 "Unexpected bytes found in DBI Stream");

455}

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

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static uint16_t toSecMapFlags(uint32_t Flags)

Definition DbiStreamBuilder.cpp:329

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

Provides write only access to a subclass of WritableBinaryStream.

Error writeArray(ArrayRef< T > Array)

Writes an array of objects of type T to the underlying stream, as if by using memcpy.

Error writeInteger(T Value)

Write the integer Value to the underlying stream in the specified endianness.

uint64_t bytesRemaining() const

LLVM_ABI Error writeStreamRef(BinaryStreamRef Ref)

Efficiently reads all data from Ref, and writes it to this stream.

Error writeEnum(T Num)

Similar to writeInteger.

Error writeObject(const T &Obj)

Writes the object Obj to the underlying stream, as if by using memcpy.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

A Module instance is used to store all the information related to an LLVM module.

StringRef - Represent a constant reference to a string, i.e.

The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.

static std::unique_ptr< WritableMappedBlockStream > createIndexedStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, uint32_t StreamIndex, BumpPtrAllocator &Allocator)

LLVM_ABI void createSectionMap(ArrayRef< llvm::object::coff_section > SecHdrs)

Definition DbiStreamBuilder.cpp:351

LLVM_ABI void addOldFpoData(const object::FpoData &Fpo)

Definition DbiStreamBuilder.cpp:81

LLVM_ABI void setPublicsStreamIndex(uint32_t Index)

Definition DbiStreamBuilder.cpp:70

LLVM_ABI void setFlags(uint16_t F)

Definition DbiStreamBuilder.cpp:53

LLVM_ABI Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File)

Definition DbiStreamBuilder.cpp:118

LLVM_ABI ~DbiStreamBuilder()

LLVM_ABI void setAge(uint32_t A)

Definition DbiStreamBuilder.cpp:37

LLVM_ABI void setGlobalsStreamIndex(uint32_t Index)

Definition DbiStreamBuilder.cpp:62

LLVM_ABI Expected< uint32_t > getSourceFileNameIndex(StringRef FileName)

Definition DbiStreamBuilder.cpp:126

LLVM_ABI Error finalizeMsfLayout()

Definition DbiStreamBuilder.cpp:288

LLVM_ABI void setSymbolRecordStreamIndex(uint32_t Index)

Definition DbiStreamBuilder.cpp:66

LLVM_ABI void addNewFpoData(const codeview::FrameData &FD)

Definition DbiStreamBuilder.cpp:74

LLVM_ABI void setVersionHeader(PdbRaw_DbiVer V)

Definition DbiStreamBuilder.cpp:35

LLVM_ABI Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef MsfBuffer)

Definition DbiStreamBuilder.cpp:383

LLVM_ABI Expected< DbiModuleDescriptorBuilder & > addModuleInfo(StringRef ModuleName)

Definition DbiStreamBuilder.cpp:111

LLVM_ABI uint32_t calculateSerializedLength() const

Definition DbiStreamBuilder.cpp:102

LLVM_ABI Error addDbgStream(pdb::DbgHeaderType Type, ArrayRef< uint8_t > Data)

Definition DbiStreamBuilder.cpp:85

LLVM_ABI uint32_t addECName(StringRef Name)

Definition DbiStreamBuilder.cpp:98

LLVM_ABI void setBuildNumber(uint16_t B)

Definition DbiStreamBuilder.cpp:39

LLVM_ABI void setPdbDllVersion(uint16_t V)

Definition DbiStreamBuilder.cpp:49

LLVM_ABI void setMachineType(PDB_Machine M)

Definition DbiStreamBuilder.cpp:55

LLVM_ABI void setPdbDllRbld(uint16_t R)

Definition DbiStreamBuilder.cpp:51

LLVM_ABI DbiStreamBuilder(msf::MSFBuilder &Msf)

Definition DbiStreamBuilder.cpp:28

const uint16_t kInvalidStreamIndex

detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t

detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_t

This is an optimization pass for GlobalISel generic memory operations.

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

ArrayRef(const T &OneElt) -> ArrayRef< T >

Error parallelForEachError(RangeTy &&R, FuncTy Fn)

Data in the SUBSEC_FRAMEDATA subection.

static const uint16_t BuildMajorShift

static const uint16_t NewVersionFormatMask

static const uint16_t BuildMajorMask

static const uint16_t BuildMinorMask

uint16_t MinorVersion : 8; uint16_t MajorVersion : 7; uint16_t NewVersionFormat : 1;

static const uint16_t BuildMinorShift