LLVM: lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

13

14using namespace llvm;

15using namespace dwarf_linker;

16using namespace dwarf_linker::parallel;

17

21 : DwarfUnit(GlobalData, ID, ""), Language(Language),

22 AcceleratorRecords(&GlobalData.getAllocator()) {

23

24 UnitName = "__artificial_type_unit";

25

27

28

37 0, 0, 1, 0, 0, 1};

38

40}

41

43 prepareDataForTreeCreation();

44

45

46

53

56

57

58 DIE *UnitDIE = DIETreeGenerator.createDIE(dwarf::DW_TAG_compile_unit, 0);

61

63 ProducerString += "llvm DWARFLinkerParallel library version ";

66 {OutOffset},

68 PatchesOffsets);

69 OutOffset += DIETreeGenerator

71 dwarf::DW_FORM_strp)

72 .second;

73

74 if (Language) {

75 OutOffset += DIETreeGenerator

77 dwarf::DW_FORM_data2, *Language)

78 .second;

79 }

80

84 PatchesOffsets);

85 OutOffset += DIETreeGenerator

87 dwarf::DW_FORM_strp)

88 .second;

89

92 DebugOffsetPatch{OutOffset, &DebugLineSection}, PatchesOffsets);

93

94 OutOffset += DIETreeGenerator

96 dwarf::DW_FORM_sec_offset, 0xbaddef)

97 .second;

98 }

99

102 PatchesOffsets);

103 OutOffset += DIETreeGenerator

105 dwarf::DW_FORM_strp)

106 .second;

107

109

110

111

112 OutOffset += DIETreeGenerator

114 dwarf::DW_FORM_sec_offset,

116 .second;

117 }

118

120 OutOffset =

121 finalizeTypeEntryRec(UnitDIE->getOffset(), UnitDIE, Types.getRoot());

122

123

124 for (uint64_t *OffsetPtr : PatchesOffsets)

126

128 });

129}

130

131void TypeUnit::prepareDataForTreeCreation() {

134

135

136

137

139

142

144 });

145 }

146

149

150 std::function<bool(const DebugTypeDeclFilePatch &LHS,

151 const DebugTypeDeclFilePatch &RHS)>

152 PatchesComparator = [&](const DebugTypeDeclFilePatch &LHS,

153 const DebugTypeDeclFilePatch &RHS) {

154 return LHS.Directory->first() < RHS.Directory->first() ||

155 (!(RHS.Directory->first() < LHS.Directory->first()) &&

156 LHS.FilePath->first() < RHS.FilePath->first());

157 };

158

159 DebugInfoSection.ListDebugTypeDeclFilePatch.sort(PatchesComparator);

160 }

161

162

164 getScalarFormForValue(

165 DebugInfoSection.ListDebugTypeDeclFilePatch.size())

166 .first;

167

168 DebugInfoSection.ListDebugTypeDeclFilePatch.forEach(

173 .str()

174 .c_str());

176 return;

177

180

181 unsigned DIESize = Patch.Die->getSize();

183 *this);

184

185 DIESize += DIEGen

186 .addScalarAttribute(dwarf::DW_AT_decl_file,

187 DeclFileForm, FileIdx)

188 .second;

190 });

191 });

192

193 if (!GlobalData.getOptions().AllowNonDeterministicOutput) {

194

198 StrPatchesComparator =

200 return LHS.String->getKey() < RHS.String->getKey();

201 };

202 OutSection.ListDebugStrPatch.sort(StrPatchesComparator);

203

208 return LHS.String->getKey() < RHS.String->getKey();

209 };

210 OutSection.ListDebugTypeStrPatch.sort(TypeStrPatchesComparator);

211 });

212 });

213 }

214

215 if (!GlobalData.getOptions().AllowNonDeterministicOutput) {

216

223 return LHS.String->getKey() < RHS.String->getKey();

224 };

225 OutSection.ListDebugLineStrPatch.sort(LineStrPatchesComparator);

226

229 TypeLineStrPatchesComparator =

232 return LHS.String->getKey() < RHS.String->getKey();

233 };

234 OutSection.ListDebugTypeLineStrPatch.sort(TypeLineStrPatchesComparator);

235 });

236 });

237 }

238}

239

242 bool HasChildren = Entry->getValue().load()->Children.empty();

244 OutOffset += DIEGen.finalizeAbbreviations(HasChildren, nullptr);

245 OutOffset += OutDIE->getSize() - 1;

246

247 if (HasChildren) {

248 Entry->getValue().load()->Children.forEach([&](TypeEntry *ChildEntry) {

249 DIE *ChildDIE = &ChildEntry->getValue().load()->getFinalDie();

250 DIEGen.addChild(ChildDIE);

251

253

254 OutOffset = finalizeTypeEntryRec(OutOffset, ChildDIE, ChildEntry);

255 });

256

257

258 OutOffset += sizeof(int8_t);

259 }

260

262 return OutOffset;

263}

264

268

269 if (Dir->first() == "") {

270 DirIdx = 0;

271 } else {

272 DirectoriesMapTy::iterator DirEntry = DirectoriesMap.find(Dir);

273 if (DirEntry == DirectoriesMap.end()) {

274

277 DirectoriesMap.insert({Dir, DirIdx});

281 } else {

282 DirIdx = DirEntry->second;

283 }

284

286 DirIdx++;

287 }

288

289 auto [FileEntry, Inserted] = FileNamesMap.try_emplace(

291 if (Inserted) {

292

296 dwarf::DW_FORM_string, FileName->getKeyData());

298 }

299

300 uint32_t FileIdx = FileEntry->second;

301 return getVersion() < 5 ? FileIdx + 1 : FileIdx;

302}

303

304std::pair<dwarf::Form, uint8_t>

305TypeUnit::getScalarFormForValue(uint64_t Value) const {

306 if (Value > 0xFFFFFFFF)

307 return std::make_pair(dwarf::DW_FORM_data8, 8);

308

309 if (Value > 0xFFFF)

310 return std::make_pair(dwarf::DW_FORM_data4, 4);

311

312 if (Value > 0xFF)

313 return std::make_pair(dwarf::DW_FORM_data2, 2);

314

315 return std::make_pair(dwarf::DW_FORM_data1, 1);

316}

317

319 if (Form == dwarf::DW_FORM_data1)

320 return 1;

321

322 if (Form == dwarf::DW_FORM_data2)

323 return 2;

324

325 if (Form == dwarf::DW_FORM_data4)

326 return 4;

327

328 if (Form == dwarf::DW_FORM_data8)

329 return 8;

330

331 if (Form == dwarf::DW_FORM_data16)

332 return 16;

333

335}

336

340

343

344

345

354 }

355

357

358

360 Tasks.push_back(

362 }

363

364

365 Tasks.push_back([&]() -> Error { return emitDebugInfo(TargetTriple); });

366

367

370 Tasks.push_back([&]() -> Error {

373 });

374 }

375

376

378

379

381

383 Tasks, [&](std::function<Error(void)> F) { return F(); }))

384 return Err;

385

387}

AMDGPU Mark last scratch load

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

Allocate memory in an ever growing pool, as if by bump-pointer.

A structured debug information entry.

unsigned getAbbrevNumber() const

unsigned getOffset() const

Get the compile/type unit relative offset of this DIE.

void setOffset(unsigned O)

static DWARFFormValue createFromPValue(dwarf::Form F, const char *V)

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

StringRef str() const

Explicit conversion to StringRef.

const ValueTy & getValue() const

StringMapEntry - This is used to represent one value that is inserted into a StringMap.

const char * getKeyData() const

getKeyData - Return the start of the string data that is the key for this value.

Triple - Helper class for working with autoconf configuration names.

LLVM Value Representation.

@ Pub

.debug_pubnames, .debug_pubtypes

This class is a helper to create output DIE tree.

std::pair< DIEValue &, size_t > addStringPlaceholderAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm)

Adds string attribute with dummy offset to the current DIE.

DIE * createDIE(dwarf::Tag DieTag, uint32_t OutOffset)

Creates a DIE of specified tag DieTag and OutOffset.

std::pair< DIEValue &, size_t > addScalarAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm, uint64_t Value)

Adds specified scalar attribute to the current DIE.

Base class for all Dwarf units(Compile unit/Type table unit).

std::string UnitName

The name of this unit.

IndexedValuesMap< const StringEntry * > DebugStringIndexMap

Maps a string into the index inside .debug_str_offsets section.

StringRef getUnitName() const

Returns this unit name.

void setOutUnitDIE(DIE *UnitDie)

Set output unit DIE.

DIE * getOutUnitDIE()

Returns output unit DIE.

This class keeps data and services common for the whole linking process.

const DWARFLinkerOptions & getOptions() const

Returns linking options.

StringPool & getStringPool()

Returns global string pool.

uint16_t getDebugStrOffsetsHeaderSize() const

Return size of header of debug_str_offsets table.

LinkingGlobalData & GlobalData

dwarf::FormParams Format

Format for sections.

const dwarf::FormParams & getFormParams() const

Return size of address.

void setOutputFormat(dwarf::FormParams Format, llvm::endianness Endianness)

Sets output format for all keeping sections.

uint16_t getVersion() const

Return DWARF version.

uint16_t getDebugInfoHeaderSize() const

Return size of header of debug_info table.

SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)

Returns descriptor for the specified section of SectionKind.

Keeps cloned data for the type DIE.

BumpPtrAllocator & getThreadLocalAllocator()

Return thread local allocator used by pool.

TypeEntry * getRoot() const

Return root for all type entries.

void sortTypes()

Sort children for each kept type entry.

Error finishCloningAndEmit(const Triple &TargetTriple)

Emits resulting dwarf based on information from DIE tree.

void createDIETree(BumpPtrAllocator &Allocator)

Generates DIE tree based on information from TypesMap.

TypeUnit(LinkingGlobalData &GlobalData, unsigned ID, std::optional< uint16_t > Language, dwarf::FormParams Format, llvm::endianness Endianess)

void spawn(std::function< void()> f)

Error emitDebugInfo(const Triple &TargetTriple)

Emit .debug_info section for unit DIEs.

Error emitDebugStringOffsetSection()

Emit the .debug_str_offsets section for current unit.

void emitPubAccelerators()

Emit .debug_pubnames and .debug_pubtypes for Unit.

Error emitAbbreviations()

Error emitDebugLine(const Triple &TargetTriple, const DWARFDebugLine::LineTable &OutLineTable)

Emit .debug_line section.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

This is an optimization pass for GlobalISel generic memory operations.

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

unsigned getULEB128Size(uint64_t Value)

Utility function to get the size of the ULEB128-encoded value.

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

Error parallelForEachError(RangeTy &&R, FuncTy Fn)

uint8_t MaxOpsPerInst

The maximum number of individual operations that may be encoded in an instruction.

uint8_t MinInstLength

The size in bytes of the smallest target machine instruction.

int8_t LineBase

This parameter affects the meaning of the special opcodes. See below.

uint8_t LineRange

This parameter affects the meaning of the special opcodes. See below.

std::vector< DWARFFormValue > IncludeDirectories

uint8_t OpcodeBase

The number assigned to the first special opcode.

std::vector< uint8_t > StandardOpcodeLengths

uint8_t DefaultIsStmt

The initial value of theis_stmtregister.

dwarf::FormParams FormParams

Version, address size (starting in v5), and DWARF32/64 format; these parameters affect interpretation...

std::vector< FileNameEntry > FileNames

A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...

SmallVector< DWARFLinkerBase::AccelTableKind, 1 > AccelTables

The accelerator table kinds.

bool AllowNonDeterministicOutput

Allow to generate valid, but non deterministic output.

This structure is used to update strings offsets into .debug_line_str.

This structure is used to update strings offsets into .debug_str.

This structure is used to keep data of the concrete section.

void notePatchWithOffsetUpdate(const T &Patch, OffsetsPtrVector &PatchesOffsetsList)

While creating patches, offsets to attributes may be partially unknown(because size of abbreviation n...