DWARFStreamer.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. //===- DwarfStreamer.cpp --------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/DWARFLinker/DWARFStreamer.h"
  9. #include "llvm/ADT/Triple.h"
  10. #include "llvm/CodeGen/NonRelocatableStringpool.h"
  11. #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
  12. #include "llvm/DebugInfo/DWARF/DWARFContext.h"
  13. #include "llvm/MC/MCAsmBackend.h"
  14. #include "llvm/MC/MCCodeEmitter.h"
  15. #include "llvm/MC/MCDwarf.h"
  16. #include "llvm/MC/MCObjectWriter.h"
  17. #include "llvm/MC/MCSection.h"
  18. #include "llvm/MC/MCStreamer.h"
  19. #include "llvm/MC/MCSubtargetInfo.h"
  20. #include "llvm/MC/MCSymbol.h"
  21. #include "llvm/MC/MCTargetOptions.h"
  22. #include "llvm/MC/MCTargetOptionsCommandFlags.h"
  23. #include "llvm/Support/LEB128.h"
  24. #include "llvm/Support/TargetRegistry.h"
  25. #include "llvm/Target/TargetOptions.h"
  26. namespace llvm {
  27. bool DwarfStreamer::init(Triple TheTriple) {
  28. std::string ErrorStr;
  29. std::string TripleName;
  30. StringRef Context = "dwarf streamer init";
  31. // Get the target.
  32. const Target *TheTarget =
  33. TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);
  34. if (!TheTarget)
  35. return error(ErrorStr, Context), false;
  36. TripleName = TheTriple.getTriple();
  37. // Create all the MC Objects.
  38. MRI.reset(TheTarget->createMCRegInfo(TripleName));
  39. if (!MRI)
  40. return error(Twine("no register info for target ") + TripleName, Context),
  41. false;
  42. MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
  43. MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
  44. if (!MAI)
  45. return error("no asm info for target " + TripleName, Context), false;
  46. MOFI.reset(new MCObjectFileInfo);
  47. MC.reset(new MCContext(MAI.get(), MRI.get(), MOFI.get()));
  48. MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, *MC);
  49. MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
  50. if (!MSTI)
  51. return error("no subtarget info for target " + TripleName, Context), false;
  52. MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions);
  53. if (!MAB)
  54. return error("no asm backend for target " + TripleName, Context), false;
  55. MII.reset(TheTarget->createMCInstrInfo());
  56. if (!MII)
  57. return error("no instr info info for target " + TripleName, Context), false;
  58. MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MC);
  59. if (!MCE)
  60. return error("no code emitter for target " + TripleName, Context), false;
  61. switch (OutFileType) {
  62. case OutputFileType::Assembly: {
  63. MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(),
  64. *MAI, *MII, *MRI);
  65. MS = TheTarget->createAsmStreamer(
  66. *MC, std::make_unique<formatted_raw_ostream>(OutFile), true, true, MIP,
  67. std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB),
  68. true);
  69. break;
  70. }
  71. case OutputFileType::Object: {
  72. MS = TheTarget->createMCObjectStreamer(
  73. TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),
  74. MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE),
  75. *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible,
  76. /*DWARFMustBeAtTheEnd*/ false);
  77. break;
  78. }
  79. }
  80. if (!MS)
  81. return error("no object streamer for target " + TripleName, Context), false;
  82. // Finally create the AsmPrinter we'll use to emit the DIEs.
  83. TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(),
  84. None));
  85. if (!TM)
  86. return error("no target machine for target " + TripleName, Context), false;
  87. Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
  88. if (!Asm)
  89. return error("no asm printer for target " + TripleName, Context), false;
  90. RangesSectionSize = 0;
  91. LocSectionSize = 0;
  92. LineSectionSize = 0;
  93. FrameSectionSize = 0;
  94. DebugInfoSectionSize = 0;
  95. return true;
  96. }
  97. void DwarfStreamer::finish() { MS->Finish(); }
  98. void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) {
  99. MS->SwitchSection(MOFI->getDwarfInfoSection());
  100. MC->setDwarfVersion(DwarfVersion);
  101. }
  102. /// Emit the compilation unit header for \p Unit in the debug_info section.
  103. ///
  104. /// A Dwarf 4 section header is encoded as:
  105. /// uint32_t Unit length (omitting this field)
  106. /// uint16_t Version
  107. /// uint32_t Abbreviation table offset
  108. /// uint8_t Address size
  109. /// Leading to a total of 11 bytes.
  110. ///
  111. /// A Dwarf 5 section header is encoded as:
  112. /// uint32_t Unit length (omitting this field)
  113. /// uint16_t Version
  114. /// uint8_t Unit type
  115. /// uint8_t Address size
  116. /// uint32_t Abbreviation table offset
  117. /// Leading to a total of 12 bytes.
  118. void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit,
  119. unsigned DwarfVersion) {
  120. switchToDebugInfoSection(DwarfVersion);
  121. /// The start of the unit within its section.
  122. Unit.setLabelBegin(Asm->createTempSymbol("cu_begin"));
  123. Asm->OutStreamer->emitLabel(Unit.getLabelBegin());
  124. // Emit size of content not including length itself. The size has already
  125. // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to
  126. // account for the length field.
  127. Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4);
  128. Asm->emitInt16(DwarfVersion);
  129. if (DwarfVersion >= 5) {
  130. Asm->emitInt8(dwarf::DW_UT_compile);
  131. Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
  132. // We share one abbreviations table across all units so it's always at the
  133. // start of the section.
  134. Asm->emitInt32(0);
  135. DebugInfoSectionSize += 12;
  136. } else {
  137. // We share one abbreviations table across all units so it's always at the
  138. // start of the section.
  139. Asm->emitInt32(0);
  140. Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
  141. DebugInfoSectionSize += 11;
  142. }
  143. // Remember this CU.
  144. EmittedUnits.push_back({Unit.getUniqueID(), Unit.getLabelBegin()});
  145. }
  146. /// Emit the \p Abbrevs array as the shared abbreviation table
  147. /// for the linked Dwarf file.
  148. void DwarfStreamer::emitAbbrevs(
  149. const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
  150. unsigned DwarfVersion) {
  151. MS->SwitchSection(MOFI->getDwarfAbbrevSection());
  152. MC->setDwarfVersion(DwarfVersion);
  153. Asm->emitDwarfAbbrevs(Abbrevs);
  154. }
  155. /// Recursively emit the DIE tree rooted at \p Die.
  156. void DwarfStreamer::emitDIE(DIE &Die) {
  157. MS->SwitchSection(MOFI->getDwarfInfoSection());
  158. Asm->emitDwarfDIE(Die);
  159. DebugInfoSectionSize += Die.getSize();
  160. }
  161. /// Emit contents of section SecName From Obj.
  162. void DwarfStreamer::emitSectionContents(StringRef SecData, StringRef SecName) {
  163. MCSection *Section =
  164. StringSwitch<MCSection *>(SecName)
  165. .Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection())
  166. .Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection())
  167. .Case("debug_ranges",
  168. MC->getObjectFileInfo()->getDwarfRangesSection())
  169. .Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection())
  170. .Case("debug_aranges",
  171. MC->getObjectFileInfo()->getDwarfARangesSection())
  172. .Default(nullptr);
  173. if (Section) {
  174. MS->SwitchSection(Section);
  175. MS->emitBytes(SecData);
  176. }
  177. }
  178. /// Emit DIE containing warnings.
  179. void DwarfStreamer::emitPaperTrailWarningsDie(DIE &Die) {
  180. switchToDebugInfoSection(/* Version */ 2);
  181. auto &Asm = getAsmPrinter();
  182. Asm.emitInt32(11 + Die.getSize() - 4);
  183. Asm.emitInt16(2);
  184. Asm.emitInt32(0);
  185. Asm.emitInt8(MOFI->getTargetTriple().isArch64Bit() ? 8 : 4);
  186. DebugInfoSectionSize += 11;
  187. emitDIE(Die);
  188. }
  189. /// Emit the debug_str section stored in \p Pool.
  190. void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) {
  191. Asm->OutStreamer->SwitchSection(MOFI->getDwarfStrSection());
  192. std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntriesForEmission();
  193. for (auto Entry : Entries) {
  194. // Emit the string itself.
  195. Asm->OutStreamer->emitBytes(Entry.getString());
  196. // Emit a null terminator.
  197. Asm->emitInt8(0);
  198. }
  199. #if 0
  200. if (DwarfVersion >= 5) {
  201. // Emit an empty string offset section.
  202. Asm->OutStreamer->SwitchSection(MOFI->getDwarfStrOffSection());
  203. Asm->emitDwarfUnitLength(4, "Length of String Offsets Set");
  204. Asm->emitInt16(DwarfVersion);
  205. Asm->emitInt16(0);
  206. }
  207. #endif
  208. }
  209. void DwarfStreamer::emitDebugNames(
  210. AccelTable<DWARF5AccelTableStaticData> &Table) {
  211. if (EmittedUnits.empty())
  212. return;
  213. // Build up data structures needed to emit this section.
  214. std::vector<MCSymbol *> CompUnits;
  215. DenseMap<unsigned, size_t> UniqueIdToCuMap;
  216. unsigned Id = 0;
  217. for (auto &CU : EmittedUnits) {
  218. CompUnits.push_back(CU.LabelBegin);
  219. // We might be omitting CUs, so we need to remap them.
  220. UniqueIdToCuMap[CU.ID] = Id++;
  221. }
  222. Asm->OutStreamer->SwitchSection(MOFI->getDwarfDebugNamesSection());
  223. emitDWARF5AccelTable(
  224. Asm.get(), Table, CompUnits,
  225. [&UniqueIdToCuMap](const DWARF5AccelTableStaticData &Entry) {
  226. return UniqueIdToCuMap[Entry.getCUIndex()];
  227. });
  228. }
  229. void DwarfStreamer::emitAppleNamespaces(
  230. AccelTable<AppleAccelTableStaticOffsetData> &Table) {
  231. Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelNamespaceSection());
  232. auto *SectionBegin = Asm->createTempSymbol("namespac_begin");
  233. Asm->OutStreamer->emitLabel(SectionBegin);
  234. emitAppleAccelTable(Asm.get(), Table, "namespac", SectionBegin);
  235. }
  236. void DwarfStreamer::emitAppleNames(
  237. AccelTable<AppleAccelTableStaticOffsetData> &Table) {
  238. Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelNamesSection());
  239. auto *SectionBegin = Asm->createTempSymbol("names_begin");
  240. Asm->OutStreamer->emitLabel(SectionBegin);
  241. emitAppleAccelTable(Asm.get(), Table, "names", SectionBegin);
  242. }
  243. void DwarfStreamer::emitAppleObjc(
  244. AccelTable<AppleAccelTableStaticOffsetData> &Table) {
  245. Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelObjCSection());
  246. auto *SectionBegin = Asm->createTempSymbol("objc_begin");
  247. Asm->OutStreamer->emitLabel(SectionBegin);
  248. emitAppleAccelTable(Asm.get(), Table, "objc", SectionBegin);
  249. }
  250. void DwarfStreamer::emitAppleTypes(
  251. AccelTable<AppleAccelTableStaticTypeData> &Table) {
  252. Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelTypesSection());
  253. auto *SectionBegin = Asm->createTempSymbol("types_begin");
  254. Asm->OutStreamer->emitLabel(SectionBegin);
  255. emitAppleAccelTable(Asm.get(), Table, "types", SectionBegin);
  256. }
  257. /// Emit the swift_ast section stored in \p Buffers.
  258. void DwarfStreamer::emitSwiftAST(StringRef Buffer) {
  259. MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
  260. SwiftASTSection->setAlignment(Align(32));
  261. MS->SwitchSection(SwiftASTSection);
  262. MS->emitBytes(Buffer);
  263. }
  264. /// Emit the debug_range section contents for \p FuncRange by
  265. /// translating the original \p Entries. The debug_range section
  266. /// format is totally trivial, consisting just of pairs of address
  267. /// sized addresses describing the ranges.
  268. void DwarfStreamer::emitRangesEntries(
  269. int64_t UnitPcOffset, uint64_t OrigLowPc,
  270. const FunctionIntervals::const_iterator &FuncRange,
  271. const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
  272. unsigned AddressSize) {
  273. MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
  274. // Offset each range by the right amount.
  275. int64_t PcOffset = Entries.empty() ? 0 : FuncRange.value() + UnitPcOffset;
  276. for (const auto &Range : Entries) {
  277. if (Range.isBaseAddressSelectionEntry(AddressSize)) {
  278. warn("unsupported base address selection operation",
  279. "emitting debug_ranges");
  280. break;
  281. }
  282. // Do not emit empty ranges.
  283. if (Range.StartAddress == Range.EndAddress)
  284. continue;
  285. // All range entries should lie in the function range.
  286. if (!(Range.StartAddress + OrigLowPc >= FuncRange.start() &&
  287. Range.EndAddress + OrigLowPc <= FuncRange.stop()))
  288. warn("inconsistent range data.", "emitting debug_ranges");
  289. MS->emitIntValue(Range.StartAddress + PcOffset, AddressSize);
  290. MS->emitIntValue(Range.EndAddress + PcOffset, AddressSize);
  291. RangesSectionSize += 2 * AddressSize;
  292. }
  293. // Add the terminator entry.
  294. MS->emitIntValue(0, AddressSize);
  295. MS->emitIntValue(0, AddressSize);
  296. RangesSectionSize += 2 * AddressSize;
  297. }
  298. /// Emit the debug_aranges contribution of a unit and
  299. /// if \p DoDebugRanges is true the debug_range contents for a
  300. /// compile_unit level DW_AT_ranges attribute (Which are basically the
  301. /// same thing with a different base address).
  302. /// Just aggregate all the ranges gathered inside that unit.
  303. void DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit,
  304. bool DoDebugRanges) {
  305. unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
  306. // Gather the ranges in a vector, so that we can simplify them. The
  307. // IntervalMap will have coalesced the non-linked ranges, but here
  308. // we want to coalesce the linked addresses.
  309. std::vector<std::pair<uint64_t, uint64_t>> Ranges;
  310. const auto &FunctionRanges = Unit.getFunctionRanges();
  311. for (auto Range = FunctionRanges.begin(), End = FunctionRanges.end();
  312. Range != End; ++Range)
  313. Ranges.push_back(std::make_pair(Range.start() + Range.value(),
  314. Range.stop() + Range.value()));
  315. // The object addresses where sorted, but again, the linked
  316. // addresses might end up in a different order.
  317. llvm::sort(Ranges);
  318. if (!Ranges.empty()) {
  319. MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
  320. MCSymbol *BeginLabel = Asm->createTempSymbol("Barange");
  321. MCSymbol *EndLabel = Asm->createTempSymbol("Earange");
  322. unsigned HeaderSize =
  323. sizeof(int32_t) + // Size of contents (w/o this field
  324. sizeof(int16_t) + // DWARF ARange version number
  325. sizeof(int32_t) + // Offset of CU in the .debug_info section
  326. sizeof(int8_t) + // Pointer Size (in bytes)
  327. sizeof(int8_t); // Segment Size (in bytes)
  328. unsigned TupleSize = AddressSize * 2;
  329. unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize));
  330. Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Arange length
  331. Asm->OutStreamer->emitLabel(BeginLabel);
  332. Asm->emitInt16(dwarf::DW_ARANGES_VERSION); // Version number
  333. Asm->emitInt32(Unit.getStartOffset()); // Corresponding unit's offset
  334. Asm->emitInt8(AddressSize); // Address size
  335. Asm->emitInt8(0); // Segment size
  336. Asm->OutStreamer->emitFill(Padding, 0x0);
  337. for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End;
  338. ++Range) {
  339. uint64_t RangeStart = Range->first;
  340. MS->emitIntValue(RangeStart, AddressSize);
  341. while ((Range + 1) != End && Range->second == (Range + 1)->first)
  342. ++Range;
  343. MS->emitIntValue(Range->second - RangeStart, AddressSize);
  344. }
  345. // Emit terminator
  346. Asm->OutStreamer->emitIntValue(0, AddressSize);
  347. Asm->OutStreamer->emitIntValue(0, AddressSize);
  348. Asm->OutStreamer->emitLabel(EndLabel);
  349. }
  350. if (!DoDebugRanges)
  351. return;
  352. MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
  353. // Offset each range by the right amount.
  354. int64_t PcOffset = -Unit.getLowPc();
  355. // Emit coalesced ranges.
  356. for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End; ++Range) {
  357. MS->emitIntValue(Range->first + PcOffset, AddressSize);
  358. while (Range + 1 != End && Range->second == (Range + 1)->first)
  359. ++Range;
  360. MS->emitIntValue(Range->second + PcOffset, AddressSize);
  361. RangesSectionSize += 2 * AddressSize;
  362. }
  363. // Add the terminator entry.
  364. MS->emitIntValue(0, AddressSize);
  365. MS->emitIntValue(0, AddressSize);
  366. RangesSectionSize += 2 * AddressSize;
  367. }
  368. /// Emit location lists for \p Unit and update attributes to point to the new
  369. /// entries.
  370. void DwarfStreamer::emitLocationsForUnit(
  371. const CompileUnit &Unit, DWARFContext &Dwarf,
  372. std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> ProcessExpr) {
  373. const auto &Attributes = Unit.getLocationAttributes();
  374. if (Attributes.empty())
  375. return;
  376. MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
  377. unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
  378. uint64_t BaseAddressMarker = (AddressSize == 8)
  379. ? std::numeric_limits<uint64_t>::max()
  380. : std::numeric_limits<uint32_t>::max();
  381. const DWARFSection &InputSec = Dwarf.getDWARFObj().getLocSection();
  382. DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
  383. DWARFUnit &OrigUnit = Unit.getOrigUnit();
  384. auto OrigUnitDie = OrigUnit.getUnitDIE(false);
  385. int64_t UnitPcOffset = 0;
  386. if (auto OrigLowPc = dwarf::toAddress(OrigUnitDie.find(dwarf::DW_AT_low_pc)))
  387. UnitPcOffset = int64_t(*OrigLowPc) - Unit.getLowPc();
  388. SmallVector<uint8_t, 32> Buffer;
  389. for (const auto &Attr : Attributes) {
  390. uint64_t Offset = Attr.first.get();
  391. Attr.first.set(LocSectionSize);
  392. // This is the quantity to add to the old location address to get
  393. // the correct address for the new one.
  394. int64_t LocPcOffset = Attr.second + UnitPcOffset;
  395. while (Data.isValidOffset(Offset)) {
  396. uint64_t Low = Data.getUnsigned(&Offset, AddressSize);
  397. uint64_t High = Data.getUnsigned(&Offset, AddressSize);
  398. LocSectionSize += 2 * AddressSize;
  399. // End of list entry.
  400. if (Low == 0 && High == 0) {
  401. Asm->OutStreamer->emitIntValue(0, AddressSize);
  402. Asm->OutStreamer->emitIntValue(0, AddressSize);
  403. break;
  404. }
  405. // Base address selection entry.
  406. if (Low == BaseAddressMarker) {
  407. Asm->OutStreamer->emitIntValue(BaseAddressMarker, AddressSize);
  408. Asm->OutStreamer->emitIntValue(High + Attr.second, AddressSize);
  409. LocPcOffset = 0;
  410. continue;
  411. }
  412. // Location list entry.
  413. Asm->OutStreamer->emitIntValue(Low + LocPcOffset, AddressSize);
  414. Asm->OutStreamer->emitIntValue(High + LocPcOffset, AddressSize);
  415. uint64_t Length = Data.getU16(&Offset);
  416. Asm->OutStreamer->emitIntValue(Length, 2);
  417. // Copy the bytes into to the buffer, process them, emit them.
  418. Buffer.reserve(Length);
  419. Buffer.resize(0);
  420. StringRef Input = InputSec.Data.substr(Offset, Length);
  421. ProcessExpr(Input, Buffer);
  422. Asm->OutStreamer->emitBytes(
  423. StringRef((const char *)Buffer.data(), Length));
  424. Offset += Length;
  425. LocSectionSize += Length + 2;
  426. }
  427. }
  428. }
  429. void DwarfStreamer::emitLineTableForUnit(MCDwarfLineTableParams Params,
  430. StringRef PrologueBytes,
  431. unsigned MinInstLength,
  432. std::vector<DWARFDebugLine::Row> &Rows,
  433. unsigned PointerSize) {
  434. // Switch to the section where the table will be emitted into.
  435. MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection());
  436. MCSymbol *LineStartSym = MC->createTempSymbol();
  437. MCSymbol *LineEndSym = MC->createTempSymbol();
  438. // The first 4 bytes is the total length of the information for this
  439. // compilation unit (not including these 4 bytes for the length).
  440. Asm->emitLabelDifference(LineEndSym, LineStartSym, 4);
  441. Asm->OutStreamer->emitLabel(LineStartSym);
  442. // Copy Prologue.
  443. MS->emitBytes(PrologueBytes);
  444. LineSectionSize += PrologueBytes.size() + 4;
  445. SmallString<128> EncodingBuffer;
  446. raw_svector_ostream EncodingOS(EncodingBuffer);
  447. if (Rows.empty()) {
  448. // We only have the dummy entry, dsymutil emits an entry with a 0
  449. // address in that case.
  450. MCDwarfLineAddr::Encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
  451. EncodingOS);
  452. MS->emitBytes(EncodingOS.str());
  453. LineSectionSize += EncodingBuffer.size();
  454. MS->emitLabel(LineEndSym);
  455. return;
  456. }
  457. // Line table state machine fields
  458. unsigned FileNum = 1;
  459. unsigned LastLine = 1;
  460. unsigned Column = 0;
  461. unsigned IsStatement = 1;
  462. unsigned Isa = 0;
  463. uint64_t Address = -1ULL;
  464. unsigned RowsSinceLastSequence = 0;
  465. for (unsigned Idx = 0; Idx < Rows.size(); ++Idx) {
  466. auto &Row = Rows[Idx];
  467. int64_t AddressDelta;
  468. if (Address == -1ULL) {
  469. MS->emitIntValue(dwarf::DW_LNS_extended_op, 1);
  470. MS->emitULEB128IntValue(PointerSize + 1);
  471. MS->emitIntValue(dwarf::DW_LNE_set_address, 1);
  472. MS->emitIntValue(Row.Address.Address, PointerSize);
  473. LineSectionSize += 2 + PointerSize + getULEB128Size(PointerSize + 1);
  474. AddressDelta = 0;
  475. } else {
  476. AddressDelta = (Row.Address.Address - Address) / MinInstLength;
  477. }
  478. // FIXME: code copied and transformed from MCDwarf.cpp::EmitDwarfLineTable.
  479. // We should find a way to share this code, but the current compatibility
  480. // requirement with classic dsymutil makes it hard. Revisit that once this
  481. // requirement is dropped.
  482. if (FileNum != Row.File) {
  483. FileNum = Row.File;
  484. MS->emitIntValue(dwarf::DW_LNS_set_file, 1);
  485. MS->emitULEB128IntValue(FileNum);
  486. LineSectionSize += 1 + getULEB128Size(FileNum);
  487. }
  488. if (Column != Row.Column) {
  489. Column = Row.Column;
  490. MS->emitIntValue(dwarf::DW_LNS_set_column, 1);
  491. MS->emitULEB128IntValue(Column);
  492. LineSectionSize += 1 + getULEB128Size(Column);
  493. }
  494. // FIXME: We should handle the discriminator here, but dsymutil doesn't
  495. // consider it, thus ignore it for now.
  496. if (Isa != Row.Isa) {
  497. Isa = Row.Isa;
  498. MS->emitIntValue(dwarf::DW_LNS_set_isa, 1);
  499. MS->emitULEB128IntValue(Isa);
  500. LineSectionSize += 1 + getULEB128Size(Isa);
  501. }
  502. if (IsStatement != Row.IsStmt) {
  503. IsStatement = Row.IsStmt;
  504. MS->emitIntValue(dwarf::DW_LNS_negate_stmt, 1);
  505. LineSectionSize += 1;
  506. }
  507. if (Row.BasicBlock) {
  508. MS->emitIntValue(dwarf::DW_LNS_set_basic_block, 1);
  509. LineSectionSize += 1;
  510. }
  511. if (Row.PrologueEnd) {
  512. MS->emitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
  513. LineSectionSize += 1;
  514. }
  515. if (Row.EpilogueBegin) {
  516. MS->emitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);
  517. LineSectionSize += 1;
  518. }
  519. int64_t LineDelta = int64_t(Row.Line) - LastLine;
  520. if (!Row.EndSequence) {
  521. MCDwarfLineAddr::Encode(*MC, Params, LineDelta, AddressDelta, EncodingOS);
  522. MS->emitBytes(EncodingOS.str());
  523. LineSectionSize += EncodingBuffer.size();
  524. EncodingBuffer.resize(0);
  525. Address = Row.Address.Address;
  526. LastLine = Row.Line;
  527. RowsSinceLastSequence++;
  528. } else {
  529. if (LineDelta) {
  530. MS->emitIntValue(dwarf::DW_LNS_advance_line, 1);
  531. MS->emitSLEB128IntValue(LineDelta);
  532. LineSectionSize += 1 + getSLEB128Size(LineDelta);
  533. }
  534. if (AddressDelta) {
  535. MS->emitIntValue(dwarf::DW_LNS_advance_pc, 1);
  536. MS->emitULEB128IntValue(AddressDelta);
  537. LineSectionSize += 1 + getULEB128Size(AddressDelta);
  538. }
  539. MCDwarfLineAddr::Encode(*MC, Params, std::numeric_limits<int64_t>::max(),
  540. 0, EncodingOS);
  541. MS->emitBytes(EncodingOS.str());
  542. LineSectionSize += EncodingBuffer.size();
  543. EncodingBuffer.resize(0);
  544. Address = -1ULL;
  545. LastLine = FileNum = IsStatement = 1;
  546. RowsSinceLastSequence = Column = Isa = 0;
  547. }
  548. }
  549. if (RowsSinceLastSequence) {
  550. MCDwarfLineAddr::Encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
  551. EncodingOS);
  552. MS->emitBytes(EncodingOS.str());
  553. LineSectionSize += EncodingBuffer.size();
  554. EncodingBuffer.resize(0);
  555. }
  556. MS->emitLabel(LineEndSym);
  557. }
  558. /// Copy the debug_line over to the updated binary while unobfuscating the file
  559. /// names and directories.
  560. void DwarfStreamer::translateLineTable(DataExtractor Data, uint64_t Offset) {
  561. MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection());
  562. StringRef Contents = Data.getData();
  563. // We have to deconstruct the line table header, because it contains to
  564. // length fields that will need to be updated when we change the length of
  565. // the files and directories in there.
  566. unsigned UnitLength = Data.getU32(&Offset);
  567. uint64_t UnitEnd = Offset + UnitLength;
  568. MCSymbol *BeginLabel = MC->createTempSymbol();
  569. MCSymbol *EndLabel = MC->createTempSymbol();
  570. unsigned Version = Data.getU16(&Offset);
  571. if (Version > 5) {
  572. warn("Unsupported line table version: dropping contents and not "
  573. "unobfsucating line table.");
  574. return;
  575. }
  576. Asm->emitLabelDifference(EndLabel, BeginLabel, 4);
  577. Asm->OutStreamer->emitLabel(BeginLabel);
  578. Asm->emitInt16(Version);
  579. LineSectionSize += 6;
  580. MCSymbol *HeaderBeginLabel = MC->createTempSymbol();
  581. MCSymbol *HeaderEndLabel = MC->createTempSymbol();
  582. Asm->emitLabelDifference(HeaderEndLabel, HeaderBeginLabel, 4);
  583. Asm->OutStreamer->emitLabel(HeaderBeginLabel);
  584. Offset += 4;
  585. LineSectionSize += 4;
  586. uint64_t AfterHeaderLengthOffset = Offset;
  587. // Skip to the directories.
  588. Offset += (Version >= 4) ? 5 : 4;
  589. unsigned OpcodeBase = Data.getU8(&Offset);
  590. Offset += OpcodeBase - 1;
  591. Asm->OutStreamer->emitBytes(Contents.slice(AfterHeaderLengthOffset, Offset));
  592. LineSectionSize += Offset - AfterHeaderLengthOffset;
  593. // Offset points to the first directory.
  594. while (const char *Dir = Data.getCStr(&Offset)) {
  595. if (Dir[0] == 0)
  596. break;
  597. StringRef Translated = Translator(Dir);
  598. Asm->OutStreamer->emitBytes(Translated);
  599. Asm->emitInt8(0);
  600. LineSectionSize += Translated.size() + 1;
  601. }
  602. Asm->emitInt8(0);
  603. LineSectionSize += 1;
  604. while (const char *File = Data.getCStr(&Offset)) {
  605. if (File[0] == 0)
  606. break;
  607. StringRef Translated = Translator(File);
  608. Asm->OutStreamer->emitBytes(Translated);
  609. Asm->emitInt8(0);
  610. LineSectionSize += Translated.size() + 1;
  611. uint64_t OffsetBeforeLEBs = Offset;
  612. Asm->emitULEB128(Data.getULEB128(&Offset));
  613. Asm->emitULEB128(Data.getULEB128(&Offset));
  614. Asm->emitULEB128(Data.getULEB128(&Offset));
  615. LineSectionSize += Offset - OffsetBeforeLEBs;
  616. }
  617. Asm->emitInt8(0);
  618. LineSectionSize += 1;
  619. Asm->OutStreamer->emitLabel(HeaderEndLabel);
  620. // Copy the actual line table program over.
  621. Asm->OutStreamer->emitBytes(Contents.slice(Offset, UnitEnd));
  622. LineSectionSize += UnitEnd - Offset;
  623. Asm->OutStreamer->emitLabel(EndLabel);
  624. Offset = UnitEnd;
  625. }
  626. /// Emit the pubnames or pubtypes section contribution for \p
  627. /// Unit into \p Sec. The data is provided in \p Names.
  628. void DwarfStreamer::emitPubSectionForUnit(
  629. MCSection *Sec, StringRef SecName, const CompileUnit &Unit,
  630. const std::vector<CompileUnit::AccelInfo> &Names) {
  631. if (Names.empty())
  632. return;
  633. // Start the dwarf pubnames section.
  634. Asm->OutStreamer->SwitchSection(Sec);
  635. MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + SecName + "_begin");
  636. MCSymbol *EndLabel = Asm->createTempSymbol("pub" + SecName + "_end");
  637. bool HeaderEmitted = false;
  638. // Emit the pubnames for this compilation unit.
  639. for (const auto &Name : Names) {
  640. if (Name.SkipPubSection)
  641. continue;
  642. if (!HeaderEmitted) {
  643. // Emit the header.
  644. Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Length
  645. Asm->OutStreamer->emitLabel(BeginLabel);
  646. Asm->emitInt16(dwarf::DW_PUBNAMES_VERSION); // Version
  647. Asm->emitInt32(Unit.getStartOffset()); // Unit offset
  648. Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset()); // Size
  649. HeaderEmitted = true;
  650. }
  651. Asm->emitInt32(Name.Die->getOffset());
  652. // Emit the string itself.
  653. Asm->OutStreamer->emitBytes(Name.Name.getString());
  654. // Emit a null terminator.
  655. Asm->emitInt8(0);
  656. }
  657. if (!HeaderEmitted)
  658. return;
  659. Asm->emitInt32(0); // End marker.
  660. Asm->OutStreamer->emitLabel(EndLabel);
  661. }
  662. /// Emit .debug_pubnames for \p Unit.
  663. void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) {
  664. if (Minimize)
  665. return;
  666. emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(),
  667. "names", Unit, Unit.getPubnames());
  668. }
  669. /// Emit .debug_pubtypes for \p Unit.
  670. void DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) {
  671. if (Minimize)
  672. return;
  673. emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(),
  674. "types", Unit, Unit.getPubtypes());
  675. }
  676. /// Emit a CIE into the debug_frame section.
  677. void DwarfStreamer::emitCIE(StringRef CIEBytes) {
  678. MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
  679. MS->emitBytes(CIEBytes);
  680. FrameSectionSize += CIEBytes.size();
  681. }
  682. /// Emit a FDE into the debug_frame section. \p FDEBytes
  683. /// contains the FDE data without the length, CIE offset and address
  684. /// which will be replaced with the parameter values.
  685. void DwarfStreamer::emitFDE(uint32_t CIEOffset, uint32_t AddrSize,
  686. uint32_t Address, StringRef FDEBytes) {
  687. MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
  688. MS->emitIntValue(FDEBytes.size() + 4 + AddrSize, 4);
  689. MS->emitIntValue(CIEOffset, 4);
  690. MS->emitIntValue(Address, AddrSize);
  691. MS->emitBytes(FDEBytes);
  692. FrameSectionSize += FDEBytes.size() + 8 + AddrSize;
  693. }
  694. } // namespace llvm