LLVM: lib/DWARFLinker/Parallel/DebugLineSectionEmitter.h Source File (original) (raw)

25public:

27 : TheTriple(TheTriple), U(U) {}

28

30

31

32

33 if (Error Err = init(TheTriple))

34 return Err;

35

36

39

40

42 uint64_t OffsetAfterUnitLength = OutSection.OS.tell();

43

44

45 emitLineTablePrologue(LineTable.Prologue, OutSection);

46

47

48 emitLineTableRows(LineTable, OutSection);

50

51

52 assert(OffsetAfterUnitLength -

54 OffsetAfterUnitLength);

55 OutSection.apply(OffsetAfterUnitLength -

57 dwarf::DW_FORM_sec_offset,

58 OffsetAfterEnd - OffsetAfterUnitLength);

59

61 }

62

63private:

65 std::string ErrorStr;

66 std::string TripleName;

67

68

69 const Target *TheTarget =

71 if (!TheTarget)

72 return createStringError(std::errc::invalid_argument, ErrorStr.c_str());

73 TripleName = TheTriple.getTriple();

74

75

79 "no register info for target %s",

80 TripleName.c_str());

81

84 if (!MAI)

86 "no asm info for target %s", TripleName.c_str());

87

89 if (!MSTI)

91 "no subtarget info for target %s",

92 TripleName.c_str());

93

94 MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr,

95 nullptr, true, "__DWARF"));

96

98 }

99

101 SectionDescriptor &Section) {

102

103 Section.emitIntVal(P.getVersion(), 2);

104 if (P.getVersion() == 5) {

105

106 Section.emitIntVal(P.getAddressSize(), 1);

107

108

109 Section.emitIntVal(P.SegSelectorSize, 1);

110 }

111

112

113 Section.emitOffset(0xBADDEF);

114

115 uint64_t OffsetAfterPrologueLength = Section.OS.tell();

116 emitLineTableProloguePayload(P, Section);

117 uint64_t OffsetAfterPrologueEnd = Section.OS.tell();

118

119

120 Section.apply(OffsetAfterPrologueLength -

121 Section.getFormParams().getDwarfOffsetByteSize(),

122 dwarf::DW_FORM_sec_offset,

123 OffsetAfterPrologueEnd - OffsetAfterPrologueLength);

124 }

125

126 void

127 emitLineTablePrologueV2IncludeAndFileTable(const DWARFDebugLine::Prologue &P,

128 SectionDescriptor &Section) {

129

130 for (const DWARFFormValue &Include : P.IncludeDirectories) {

132 if (!IncludeStr) {

133 U.warn("cann't read string from line table.");

134 return;

135 }

136

138 }

139

140 Section.emitIntVal(0, 1);

141

142

143 for (const DWARFDebugLine::FileNameEntry &File : P.FileNames) {

145 if (!FileNameStr) {

146 U.warn("cann't read string from line table.");

147 return;

148 }

149

150

151

152 Section.emitString(File.Name.getForm(), *FileNameStr);

153

154

155

157

158

160

161

163 }

164

165 Section.emitIntVal(0, 1);

166 }

167

168 void

169 emitLineTablePrologueV5IncludeAndFileTable(const DWARFDebugLine::Prologue &P,

170 SectionDescriptor &Section) {

171 if (P.IncludeDirectories.empty()) {

172

173 Section.emitIntVal(0, 1);

174 } else {

175

176 Section.emitIntVal(1, 1);

177

178

181 }

182

183

185

186 for (auto Include : P.IncludeDirectories) {

188 if (!IncludeStr) {

189 U.warn("cann't read string from line table.");

190 return;

191 }

192

194 }

195

196 bool HasChecksums = P.ContentTypes.HasMD5;

197 bool HasInlineSources = P.ContentTypes.HasSource;

198

199 dwarf::Form FileNameForm = dwarf::DW_FORM_string;

200 dwarf::Form LLVMSourceForm = dwarf::DW_FORM_string;

201

202 if (P.FileNames.empty()) {

203

204 Section.emitIntVal(0, 1);

205 } else {

206 FileNameForm = P.FileNames[0].Name.getForm();

207 LLVMSourceForm = P.FileNames[0].Source.getForm();

208

209

211 2 + (HasChecksums ? 1 : 0) + (HasInlineSources ? 1 : 0), 1);

212

213

216

219

220 if (HasChecksums) {

223 }

224

225 if (HasInlineSources) {

228 }

229 }

230

231

233

234

235 for (auto File : P.FileNames) {

237 if (!FileNameStr) {

238 U.warn("cann't read string from line table.");

239 return;

240 }

241

242

243

244 Section.emitString(FileNameForm, *FileNameStr);

246

247 if (HasChecksums) {

248 assert((File.Checksum.size() == 16) &&

249 "checksum size is not equal to 16 bytes.");

251 StringRef(reinterpret_cast<const char *>(File.Checksum.data()),

252 File.Checksum.size()));

253 }

254

255 if (HasInlineSources) {

256 std::optional<const char *> FileSourceStr =

258 if (!FileSourceStr) {

259 U.warn("cann't read string from line table.");

260 return;

261 }

262

263 Section.emitString(LLVMSourceForm, *FileSourceStr);

264 }

265 }

266 }

267

268 void emitLineTableProloguePayload(const DWARFDebugLine::Prologue &P,

269 SectionDescriptor &Section) {

270

271 Section.emitIntVal(P.MinInstLength, 1);

272 if (P.FormParams.Version >= 4) {

273

274 Section.emitIntVal(P.MaxOpsPerInst, 1);

275 }

276

277 Section.emitIntVal(P.DefaultIsStmt, 1);

278

279 Section.emitIntVal(P.LineBase, 1);

280

281 Section.emitIntVal(P.LineRange, 1);

282

283 Section.emitIntVal(P.OpcodeBase, 1);

284

285

286 for (auto Length : P.StandardOpcodeLengths)

288

289 if (P.FormParams.Version < 5)

290 emitLineTablePrologueV2IncludeAndFileTable(P, Section);

291 else

292 emitLineTablePrologueV5IncludeAndFileTable(P, Section);

293 }

294

295 void emitLineTableRows(const DWARFDebugLine::LineTable &LineTable,

296 SectionDescriptor &Section) {

297

298 MCDwarfLineTableParams Params;

299 Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;

300 Params.DWARF2LineBase = LineTable.Prologue.LineBase;

301 Params.DWARF2LineRange = LineTable.Prologue.LineRange;

302

303 SmallString<128> EncodingBuffer;

304

305 if (LineTable.Rows.empty()) {

306

307

309 0, EncodingBuffer);

310 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());

311 return;

312 }

313

314

315 unsigned FileNum = 1;

316 unsigned LastLine = 1;

317 unsigned Column = 0;

319 unsigned IsStatement = 1;

320 unsigned Isa = 0;

321 uint64_t Address = -1ULL;

322

323 unsigned RowsSinceLastSequence = 0;

324

325 for (const DWARFDebugLine::Row &Row : LineTable.Rows) {

328 Section.emitIntVal(dwarf::DW_LNS_extended_op, 1);

330 Section.emitIntVal(dwarf::DW_LNE_set_address, 1);

331 Section.emitIntVal(Row.Address.Address,

332 Section.getFormParams().AddrSize);

334 } else {

336 (Row.Address.Address - Address) / LineTable.Prologue.MinInstLength;

337 }

338

339

340

341

342

343

344 if (FileNum != Row.File) {

345 FileNum = Row.File;

346 Section.emitIntVal(dwarf::DW_LNS_set_file, 1);

348 }

349 if (Column != Row.Column) {

350 Column = Row.Column;

351 Section.emitIntVal(dwarf::DW_LNS_set_column, 1);

353 }

354 if (Discriminator != Row.Discriminator && MC->getDwarfVersion() >= 4) {

357 Section.emitIntVal(dwarf::DW_LNS_extended_op, 1);

359 Section.emitIntVal(dwarf::DW_LNE_set_discriminator, 1);

361 }

363

364 if (Isa != Row.Isa) {

365 Isa = Row.Isa;

366 Section.emitIntVal(dwarf::DW_LNS_set_isa, 1);

368 }

369 if (IsStatement != Row.IsStmt) {

370 IsStatement = Row.IsStmt;

371 Section.emitIntVal(dwarf::DW_LNS_negate_stmt, 1);

372 }

373 if (Row.BasicBlock)

374 Section.emitIntVal(dwarf::DW_LNS_set_basic_block, 1);

375

376 if (Row.PrologueEnd)

377 Section.emitIntVal(dwarf::DW_LNS_set_prologue_end, 1);

378

379 if (Row.EpilogueBegin)

380 Section.emitIntVal(dwarf::DW_LNS_set_epilogue_begin, 1);

381

382 int64_t LineDelta = int64_t(Row.Line) - LastLine;

383 if (!Row.EndSequence) {

385 EncodingBuffer);

386 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());

387 EncodingBuffer.resize(0);

388 Address = Row.Address.Address;

389 LastLine = Row.Line;

390 RowsSinceLastSequence++;

391 } else {

392 if (LineDelta) {

393 Section.emitIntVal(dwarf::DW_LNS_advance_line, 1);

395 }

397 Section.emitIntVal(dwarf::DW_LNS_advance_pc, 1);

399 }

401 std::numeric_limits<int64_t>::max(), 0,

402 EncodingBuffer);

403 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());

404 EncodingBuffer.resize(0);

406 LastLine = FileNum = IsStatement = 1;

407 RowsSinceLastSequence = Column = Discriminator = Isa = 0;

408 }

409 }

410

411 if (RowsSinceLastSequence) {

413 0, EncodingBuffer);

414 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());

415 EncodingBuffer.resize(0);

416 }

417 }

418

419 Triple TheTriple;

420 DwarfUnit &U;

421

422 std::unique_ptr MRI;

423 std::unique_ptr MAI;

424 std::unique_ptr MC;

425 std::unique_ptr MSTI;

426};