DWP.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. //===-- llvm-dwp.cpp - Split DWARF merging tool for llvm ------------------===//
  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. //
  9. // A utility for merging DWARF 5 Split DWARF .dwo files into .dwp (DWARF
  10. // package files).
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/DWP/DWP.h"
  14. #include "llvm/DWP/DWPError.h"
  15. #include "llvm/MC/MCContext.h"
  16. #include "llvm/MC/MCObjectFileInfo.h"
  17. #include "llvm/MC/MCTargetOptionsCommandFlags.h"
  18. #include "llvm/Object/Decompressor.h"
  19. using namespace llvm;
  20. using namespace llvm::object;
  21. static mc::RegisterMCTargetOptionsFlags MCTargetOptionsFlags;
  22. // Returns the size of debug_str_offsets section headers in bytes.
  23. static uint64_t debugStrOffsetsHeaderSize(DataExtractor StrOffsetsData,
  24. uint16_t DwarfVersion) {
  25. if (DwarfVersion <= 4)
  26. return 0; // There is no header before dwarf 5.
  27. uint64_t Offset = 0;
  28. uint64_t Length = StrOffsetsData.getU32(&Offset);
  29. if (Length == llvm::dwarf::DW_LENGTH_DWARF64)
  30. return 16; // unit length: 12 bytes, version: 2 bytes, padding: 2 bytes.
  31. return 8; // unit length: 4 bytes, version: 2 bytes, padding: 2 bytes.
  32. }
  33. static uint64_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) {
  34. uint64_t Offset = 0;
  35. DataExtractor AbbrevData(Abbrev, true, 0);
  36. while (AbbrevData.getULEB128(&Offset) != AbbrCode) {
  37. // Tag
  38. AbbrevData.getULEB128(&Offset);
  39. // DW_CHILDREN
  40. AbbrevData.getU8(&Offset);
  41. // Attributes
  42. while (AbbrevData.getULEB128(&Offset) | AbbrevData.getULEB128(&Offset))
  43. ;
  44. }
  45. return Offset;
  46. }
  47. static Expected<const char *>
  48. getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint64_t &InfoOffset,
  49. StringRef StrOffsets, StringRef Str, uint16_t Version) {
  50. if (Form == dwarf::DW_FORM_string)
  51. return InfoData.getCStr(&InfoOffset);
  52. uint64_t StrIndex;
  53. switch (Form) {
  54. case dwarf::DW_FORM_strx1:
  55. StrIndex = InfoData.getU8(&InfoOffset);
  56. break;
  57. case dwarf::DW_FORM_strx2:
  58. StrIndex = InfoData.getU16(&InfoOffset);
  59. break;
  60. case dwarf::DW_FORM_strx3:
  61. StrIndex = InfoData.getU24(&InfoOffset);
  62. break;
  63. case dwarf::DW_FORM_strx4:
  64. StrIndex = InfoData.getU32(&InfoOffset);
  65. break;
  66. case dwarf::DW_FORM_strx:
  67. case dwarf::DW_FORM_GNU_str_index:
  68. StrIndex = InfoData.getULEB128(&InfoOffset);
  69. break;
  70. default:
  71. return make_error<DWPError>(
  72. "string field must be encoded with one of the following: "
  73. "DW_FORM_string, DW_FORM_strx, DW_FORM_strx1, DW_FORM_strx2, "
  74. "DW_FORM_strx3, DW_FORM_strx4, or DW_FORM_GNU_str_index.");
  75. }
  76. DataExtractor StrOffsetsData(StrOffsets, true, 0);
  77. uint64_t StrOffsetsOffset = 4 * StrIndex;
  78. StrOffsetsOffset += debugStrOffsetsHeaderSize(StrOffsetsData, Version);
  79. uint64_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
  80. DataExtractor StrData(Str, true, 0);
  81. return StrData.getCStr(&StrOffset);
  82. }
  83. static Expected<CompileUnitIdentifiers>
  84. getCUIdentifiers(InfoSectionUnitHeader &Header, StringRef Abbrev,
  85. StringRef Info, StringRef StrOffsets, StringRef Str) {
  86. DataExtractor InfoData(Info, true, 0);
  87. uint64_t Offset = Header.HeaderSize;
  88. if (Header.Version >= 5 && Header.UnitType != dwarf::DW_UT_split_compile)
  89. return make_error<DWPError>(
  90. std::string("unit type DW_UT_split_compile type not found in "
  91. "debug_info header. Unexpected unit type 0x" +
  92. utostr(Header.UnitType) + " found"));
  93. CompileUnitIdentifiers ID;
  94. uint32_t AbbrCode = InfoData.getULEB128(&Offset);
  95. DataExtractor AbbrevData(Abbrev, true, 0);
  96. uint64_t AbbrevOffset = getCUAbbrev(Abbrev, AbbrCode);
  97. auto Tag = static_cast<dwarf::Tag>(AbbrevData.getULEB128(&AbbrevOffset));
  98. if (Tag != dwarf::DW_TAG_compile_unit)
  99. return make_error<DWPError>("top level DIE is not a compile unit");
  100. // DW_CHILDREN
  101. AbbrevData.getU8(&AbbrevOffset);
  102. uint32_t Name;
  103. dwarf::Form Form;
  104. while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) |
  105. (Form = static_cast<dwarf::Form>(
  106. AbbrevData.getULEB128(&AbbrevOffset))) &&
  107. (Name != 0 || Form != 0)) {
  108. switch (Name) {
  109. case dwarf::DW_AT_name: {
  110. Expected<const char *> EName = getIndexedString(
  111. Form, InfoData, Offset, StrOffsets, Str, Header.Version);
  112. if (!EName)
  113. return EName.takeError();
  114. ID.Name = *EName;
  115. break;
  116. }
  117. case dwarf::DW_AT_GNU_dwo_name:
  118. case dwarf::DW_AT_dwo_name: {
  119. Expected<const char *> EName = getIndexedString(
  120. Form, InfoData, Offset, StrOffsets, Str, Header.Version);
  121. if (!EName)
  122. return EName.takeError();
  123. ID.DWOName = *EName;
  124. break;
  125. }
  126. case dwarf::DW_AT_GNU_dwo_id:
  127. Header.Signature = InfoData.getU64(&Offset);
  128. break;
  129. default:
  130. DWARFFormValue::skipValue(
  131. Form, InfoData, &Offset,
  132. dwarf::FormParams({Header.Version, Header.AddrSize, Header.Format}));
  133. }
  134. }
  135. if (!Header.Signature)
  136. return make_error<DWPError>("compile unit missing dwo_id");
  137. ID.Signature = *Header.Signature;
  138. return ID;
  139. }
  140. static bool isSupportedSectionKind(DWARFSectionKind Kind) {
  141. return Kind != DW_SECT_EXT_unknown;
  142. }
  143. namespace llvm {
  144. // Convert an internal section identifier into the index to use with
  145. // UnitIndexEntry::Contributions.
  146. unsigned getContributionIndex(DWARFSectionKind Kind, uint32_t IndexVersion) {
  147. assert(serializeSectionKind(Kind, IndexVersion) >= DW_SECT_INFO);
  148. return serializeSectionKind(Kind, IndexVersion) - DW_SECT_INFO;
  149. }
  150. } // namespace llvm
  151. // Convert a UnitIndexEntry::Contributions index to the corresponding on-disk
  152. // value of the section identifier.
  153. static unsigned getOnDiskSectionId(unsigned Index) {
  154. return Index + DW_SECT_INFO;
  155. }
  156. static StringRef getSubsection(StringRef Section,
  157. const DWARFUnitIndex::Entry &Entry,
  158. DWARFSectionKind Kind) {
  159. const auto *Off = Entry.getContribution(Kind);
  160. if (!Off)
  161. return StringRef();
  162. return Section.substr(Off->Offset, Off->Length);
  163. }
  164. static void
  165. addAllTypesFromDWP(MCStreamer &Out,
  166. MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
  167. const DWARFUnitIndex &TUIndex, MCSection *OutputTypes,
  168. StringRef Types, const UnitIndexEntry &TUEntry,
  169. uint32_t &TypesOffset, unsigned TypesContributionIndex) {
  170. Out.SwitchSection(OutputTypes);
  171. for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) {
  172. auto *I = E.getContributions();
  173. if (!I)
  174. continue;
  175. auto P = TypeIndexEntries.insert(std::make_pair(E.getSignature(), TUEntry));
  176. if (!P.second)
  177. continue;
  178. auto &Entry = P.first->second;
  179. // Zero out the debug_info contribution
  180. Entry.Contributions[0] = {};
  181. for (auto Kind : TUIndex.getColumnKinds()) {
  182. if (!isSupportedSectionKind(Kind))
  183. continue;
  184. auto &C =
  185. Entry.Contributions[getContributionIndex(Kind, TUIndex.getVersion())];
  186. C.Offset += I->Offset;
  187. C.Length = I->Length;
  188. ++I;
  189. }
  190. auto &C = Entry.Contributions[TypesContributionIndex];
  191. Out.emitBytes(Types.substr(
  192. C.Offset - TUEntry.Contributions[TypesContributionIndex].Offset,
  193. C.Length));
  194. C.Offset = TypesOffset;
  195. TypesOffset += C.Length;
  196. }
  197. }
  198. static void addAllTypesFromTypesSection(
  199. MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
  200. MCSection *OutputTypes, const std::vector<StringRef> &TypesSections,
  201. const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) {
  202. for (StringRef Types : TypesSections) {
  203. Out.SwitchSection(OutputTypes);
  204. uint64_t Offset = 0;
  205. DataExtractor Data(Types, true, 0);
  206. while (Data.isValidOffset(Offset)) {
  207. UnitIndexEntry Entry = CUEntry;
  208. // Zero out the debug_info contribution
  209. Entry.Contributions[0] = {};
  210. auto &C = Entry.Contributions[getContributionIndex(DW_SECT_EXT_TYPES, 2)];
  211. C.Offset = TypesOffset;
  212. auto PrevOffset = Offset;
  213. // Length of the unit, including the 4 byte length field.
  214. C.Length = Data.getU32(&Offset) + 4;
  215. Data.getU16(&Offset); // Version
  216. Data.getU32(&Offset); // Abbrev offset
  217. Data.getU8(&Offset); // Address size
  218. auto Signature = Data.getU64(&Offset);
  219. Offset = PrevOffset + C.Length;
  220. auto P = TypeIndexEntries.insert(std::make_pair(Signature, Entry));
  221. if (!P.second)
  222. continue;
  223. Out.emitBytes(Types.substr(PrevOffset, C.Length));
  224. TypesOffset += C.Length;
  225. }
  226. }
  227. }
  228. static std::string buildDWODescription(StringRef Name, StringRef DWPName,
  229. StringRef DWOName) {
  230. std::string Text = "\'";
  231. Text += Name;
  232. Text += '\'';
  233. if (!DWPName.empty()) {
  234. Text += " (from ";
  235. if (!DWOName.empty()) {
  236. Text += '\'';
  237. Text += DWOName;
  238. Text += "' in ";
  239. }
  240. Text += '\'';
  241. Text += DWPName;
  242. Text += "')";
  243. }
  244. return Text;
  245. }
  246. static Error createError(StringRef Name, Error E) {
  247. return make_error<DWPError>(
  248. ("failure while decompressing compressed section: '" + Name + "', " +
  249. llvm::toString(std::move(E)))
  250. .str());
  251. }
  252. static Error
  253. handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections,
  254. StringRef &Name, StringRef &Contents) {
  255. if (!Decompressor::isGnuStyle(Name))
  256. return Error::success();
  257. Expected<Decompressor> Dec =
  258. Decompressor::create(Name, Contents, false /*IsLE*/, false /*Is64Bit*/);
  259. if (!Dec)
  260. return createError(Name, Dec.takeError());
  261. UncompressedSections.emplace_back();
  262. if (Error E = Dec->resizeAndDecompress(UncompressedSections.back()))
  263. return createError(Name, std::move(E));
  264. Name = Name.substr(2); // Drop ".z"
  265. Contents = UncompressedSections.back();
  266. return Error::success();
  267. }
  268. namespace llvm {
  269. // Parse and return the header of an info section compile/type unit.
  270. Expected<InfoSectionUnitHeader> parseInfoSectionUnitHeader(StringRef Info) {
  271. InfoSectionUnitHeader Header;
  272. Error Err = Error::success();
  273. uint64_t Offset = 0;
  274. DWARFDataExtractor InfoData(Info, true, 0);
  275. std::tie(Header.Length, Header.Format) =
  276. InfoData.getInitialLength(&Offset, &Err);
  277. if (Err)
  278. return make_error<DWPError>("cannot parse compile unit length: " +
  279. llvm::toString(std::move(Err)));
  280. if (!InfoData.isValidOffset(Offset + (Header.Length - 1))) {
  281. return make_error<DWPError>(
  282. "compile unit exceeds .debug_info section range: " +
  283. utostr(Offset + Header.Length) + " >= " + utostr(InfoData.size()));
  284. }
  285. Header.Version = InfoData.getU16(&Offset, &Err);
  286. if (Err)
  287. return make_error<DWPError>("cannot parse compile unit version: " +
  288. llvm::toString(std::move(Err)));
  289. uint64_t MinHeaderLength;
  290. if (Header.Version >= 5) {
  291. // Size: Version (2), UnitType (1), AddrSize (1), DebugAbbrevOffset (4),
  292. // Signature (8)
  293. MinHeaderLength = 16;
  294. } else {
  295. // Size: Version (2), DebugAbbrevOffset (4), AddrSize (1)
  296. MinHeaderLength = 7;
  297. }
  298. if (Header.Length < MinHeaderLength) {
  299. return make_error<DWPError>("unit length is too small: expected at least " +
  300. utostr(MinHeaderLength) + " got " +
  301. utostr(Header.Length) + ".");
  302. }
  303. if (Header.Version >= 5) {
  304. Header.UnitType = InfoData.getU8(&Offset);
  305. Header.AddrSize = InfoData.getU8(&Offset);
  306. Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
  307. Header.Signature = InfoData.getU64(&Offset);
  308. if (Header.UnitType == dwarf::DW_UT_split_type) {
  309. // Type offset.
  310. MinHeaderLength += 4;
  311. if (Header.Length < MinHeaderLength)
  312. return make_error<DWPError>("type unit is missing type offset");
  313. InfoData.getU32(&Offset);
  314. }
  315. } else {
  316. // Note that, address_size and debug_abbrev_offset fields have switched
  317. // places between dwarf version 4 and 5.
  318. Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
  319. Header.AddrSize = InfoData.getU8(&Offset);
  320. }
  321. Header.HeaderSize = Offset;
  322. return Header;
  323. }
  324. void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings,
  325. MCSection *StrOffsetSection,
  326. StringRef CurStrSection,
  327. StringRef CurStrOffsetSection, uint16_t Version) {
  328. // Could possibly produce an error or warning if one of these was non-null but
  329. // the other was null.
  330. if (CurStrSection.empty() || CurStrOffsetSection.empty())
  331. return;
  332. DenseMap<uint64_t, uint32_t> OffsetRemapping;
  333. DataExtractor Data(CurStrSection, true, 0);
  334. uint64_t LocalOffset = 0;
  335. uint64_t PrevOffset = 0;
  336. while (const char *S = Data.getCStr(&LocalOffset)) {
  337. OffsetRemapping[PrevOffset] =
  338. Strings.getOffset(S, LocalOffset - PrevOffset);
  339. PrevOffset = LocalOffset;
  340. }
  341. Data = DataExtractor(CurStrOffsetSection, true, 0);
  342. Out.SwitchSection(StrOffsetSection);
  343. uint64_t HeaderSize = debugStrOffsetsHeaderSize(Data, Version);
  344. uint64_t Offset = 0;
  345. uint64_t Size = CurStrOffsetSection.size();
  346. // FIXME: This can be caused by bad input and should be handled as such.
  347. assert(HeaderSize <= Size && "StrOffsetSection size is less than its header");
  348. // Copy the header to the output.
  349. Out.emitBytes(Data.getBytes(&Offset, HeaderSize));
  350. while (Offset < Size) {
  351. auto OldOffset = Data.getU32(&Offset);
  352. auto NewOffset = OffsetRemapping[OldOffset];
  353. Out.emitIntValue(NewOffset, 4);
  354. }
  355. }
  356. void writeIndexTable(
  357. MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets,
  358. const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
  359. uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field) {
  360. for (const auto &E : IndexEntries)
  361. for (size_t I = 0; I != array_lengthof(E.second.Contributions); ++I)
  362. if (ContributionOffsets[I])
  363. Out.emitIntValue(E.second.Contributions[I].*Field, 4);
  364. }
  365. void writeIndex(MCStreamer &Out, MCSection *Section,
  366. ArrayRef<unsigned> ContributionOffsets,
  367. const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
  368. uint32_t IndexVersion) {
  369. if (IndexEntries.empty())
  370. return;
  371. unsigned Columns = 0;
  372. for (auto &C : ContributionOffsets)
  373. if (C)
  374. ++Columns;
  375. std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2));
  376. uint64_t Mask = Buckets.size() - 1;
  377. size_t I = 0;
  378. for (const auto &P : IndexEntries) {
  379. auto S = P.first;
  380. auto H = S & Mask;
  381. auto HP = ((S >> 32) & Mask) | 1;
  382. while (Buckets[H]) {
  383. assert(S != IndexEntries.begin()[Buckets[H] - 1].first &&
  384. "Duplicate unit");
  385. H = (H + HP) & Mask;
  386. }
  387. Buckets[H] = I + 1;
  388. ++I;
  389. }
  390. Out.SwitchSection(Section);
  391. Out.emitIntValue(IndexVersion, 4); // Version
  392. Out.emitIntValue(Columns, 4); // Columns
  393. Out.emitIntValue(IndexEntries.size(), 4); // Num Units
  394. Out.emitIntValue(Buckets.size(), 4); // Num Buckets
  395. // Write the signatures.
  396. for (const auto &I : Buckets)
  397. Out.emitIntValue(I ? IndexEntries.begin()[I - 1].first : 0, 8);
  398. // Write the indexes.
  399. for (const auto &I : Buckets)
  400. Out.emitIntValue(I, 4);
  401. // Write the column headers (which sections will appear in the table)
  402. for (size_t I = 0; I != ContributionOffsets.size(); ++I)
  403. if (ContributionOffsets[I])
  404. Out.emitIntValue(getOnDiskSectionId(I), 4);
  405. // Write the offsets.
  406. writeIndexTable(Out, ContributionOffsets, IndexEntries,
  407. &DWARFUnitIndex::Entry::SectionContribution::Offset);
  408. // Write the lengths.
  409. writeIndexTable(Out, ContributionOffsets, IndexEntries,
  410. &DWARFUnitIndex::Entry::SectionContribution::Length);
  411. }
  412. Error buildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
  413. const CompileUnitIdentifiers &ID, StringRef DWPName) {
  414. return make_error<DWPError>(
  415. std::string("duplicate DWO ID (") + utohexstr(PrevE.first) + ") in " +
  416. buildDWODescription(PrevE.second.Name, PrevE.second.DWPName,
  417. PrevE.second.DWOName) +
  418. " and " + buildDWODescription(ID.Name, DWPName, ID.DWOName));
  419. }
  420. Error handleSection(
  421. const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
  422. const MCSection *StrSection, const MCSection *StrOffsetSection,
  423. const MCSection *TypesSection, const MCSection *CUIndexSection,
  424. const MCSection *TUIndexSection, const MCSection *InfoSection,
  425. const SectionRef &Section, MCStreamer &Out,
  426. std::deque<SmallString<32>> &UncompressedSections,
  427. uint32_t (&ContributionOffsets)[8], UnitIndexEntry &CurEntry,
  428. StringRef &CurStrSection, StringRef &CurStrOffsetSection,
  429. std::vector<StringRef> &CurTypesSection,
  430. std::vector<StringRef> &CurInfoSection, StringRef &AbbrevSection,
  431. StringRef &CurCUIndexSection, StringRef &CurTUIndexSection,
  432. std::vector<std::pair<DWARFSectionKind, uint32_t>> &SectionLength) {
  433. if (Section.isBSS())
  434. return Error::success();
  435. if (Section.isVirtual())
  436. return Error::success();
  437. Expected<StringRef> NameOrErr = Section.getName();
  438. if (!NameOrErr)
  439. return NameOrErr.takeError();
  440. StringRef Name = *NameOrErr;
  441. Expected<StringRef> ContentsOrErr = Section.getContents();
  442. if (!ContentsOrErr)
  443. return ContentsOrErr.takeError();
  444. StringRef Contents = *ContentsOrErr;
  445. if (auto Err = handleCompressedSection(UncompressedSections, Name, Contents))
  446. return Err;
  447. Name = Name.substr(Name.find_first_not_of("._"));
  448. auto SectionPair = KnownSections.find(Name);
  449. if (SectionPair == KnownSections.end())
  450. return Error::success();
  451. if (DWARFSectionKind Kind = SectionPair->second.second) {
  452. if (Kind != DW_SECT_EXT_TYPES && Kind != DW_SECT_INFO) {
  453. SectionLength.push_back(std::make_pair(Kind, Contents.size()));
  454. }
  455. if (Kind == DW_SECT_ABBREV) {
  456. AbbrevSection = Contents;
  457. }
  458. }
  459. MCSection *OutSection = SectionPair->second.first;
  460. if (OutSection == StrOffsetSection)
  461. CurStrOffsetSection = Contents;
  462. else if (OutSection == StrSection)
  463. CurStrSection = Contents;
  464. else if (OutSection == TypesSection)
  465. CurTypesSection.push_back(Contents);
  466. else if (OutSection == CUIndexSection)
  467. CurCUIndexSection = Contents;
  468. else if (OutSection == TUIndexSection)
  469. CurTUIndexSection = Contents;
  470. else if (OutSection == InfoSection)
  471. CurInfoSection.push_back(Contents);
  472. else {
  473. Out.SwitchSection(OutSection);
  474. Out.emitBytes(Contents);
  475. }
  476. return Error::success();
  477. }
  478. Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
  479. const auto &MCOFI = *Out.getContext().getObjectFileInfo();
  480. MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
  481. MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
  482. MCSection *const TypesSection = MCOFI.getDwarfTypesDWOSection();
  483. MCSection *const CUIndexSection = MCOFI.getDwarfCUIndexSection();
  484. MCSection *const TUIndexSection = MCOFI.getDwarfTUIndexSection();
  485. MCSection *const InfoSection = MCOFI.getDwarfInfoDWOSection();
  486. const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
  487. {"debug_info.dwo", {InfoSection, DW_SECT_INFO}},
  488. {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}},
  489. {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
  490. {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
  491. {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}},
  492. {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
  493. {"debug_macro.dwo", {MCOFI.getDwarfMacroDWOSection(), DW_SECT_MACRO}},
  494. {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
  495. {"debug_loclists.dwo",
  496. {MCOFI.getDwarfLoclistsDWOSection(), DW_SECT_LOCLISTS}},
  497. {"debug_rnglists.dwo",
  498. {MCOFI.getDwarfRnglistsDWOSection(), DW_SECT_RNGLISTS}},
  499. {"debug_cu_index", {CUIndexSection, static_cast<DWARFSectionKind>(0)}},
  500. {"debug_tu_index", {TUIndexSection, static_cast<DWARFSectionKind>(0)}}};
  501. MapVector<uint64_t, UnitIndexEntry> IndexEntries;
  502. MapVector<uint64_t, UnitIndexEntry> TypeIndexEntries;
  503. uint32_t ContributionOffsets[8] = {};
  504. uint16_t Version = 0;
  505. uint32_t IndexVersion = 0;
  506. DWPStringPool Strings(Out, StrSection);
  507. SmallVector<OwningBinary<object::ObjectFile>, 128> Objects;
  508. Objects.reserve(Inputs.size());
  509. std::deque<SmallString<32>> UncompressedSections;
  510. for (const auto &Input : Inputs) {
  511. auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
  512. if (!ErrOrObj)
  513. return ErrOrObj.takeError();
  514. auto &Obj = *ErrOrObj->getBinary();
  515. Objects.push_back(std::move(*ErrOrObj));
  516. UnitIndexEntry CurEntry = {};
  517. StringRef CurStrSection;
  518. StringRef CurStrOffsetSection;
  519. std::vector<StringRef> CurTypesSection;
  520. std::vector<StringRef> CurInfoSection;
  521. StringRef AbbrevSection;
  522. StringRef CurCUIndexSection;
  523. StringRef CurTUIndexSection;
  524. // This maps each section contained in this file to its length.
  525. // This information is later on used to calculate the contributions,
  526. // i.e. offset and length, of each compile/type unit to a section.
  527. std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength;
  528. for (const auto &Section : Obj.sections())
  529. if (auto Err = handleSection(
  530. KnownSections, StrSection, StrOffsetSection, TypesSection,
  531. CUIndexSection, TUIndexSection, InfoSection, Section, Out,
  532. UncompressedSections, ContributionOffsets, CurEntry,
  533. CurStrSection, CurStrOffsetSection, CurTypesSection,
  534. CurInfoSection, AbbrevSection, CurCUIndexSection,
  535. CurTUIndexSection, SectionLength))
  536. return Err;
  537. if (CurInfoSection.empty())
  538. continue;
  539. Expected<InfoSectionUnitHeader> HeaderOrErr =
  540. parseInfoSectionUnitHeader(CurInfoSection.front());
  541. if (!HeaderOrErr)
  542. return HeaderOrErr.takeError();
  543. InfoSectionUnitHeader &Header = *HeaderOrErr;
  544. if (Version == 0) {
  545. Version = Header.Version;
  546. IndexVersion = Version < 5 ? 2 : 5;
  547. } else if (Version != Header.Version) {
  548. return make_error<DWPError>("incompatible DWARF compile unit versions.");
  549. }
  550. writeStringsAndOffsets(Out, Strings, StrOffsetSection, CurStrSection,
  551. CurStrOffsetSection, Header.Version);
  552. for (auto Pair : SectionLength) {
  553. auto Index = getContributionIndex(Pair.first, IndexVersion);
  554. CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
  555. ContributionOffsets[Index] +=
  556. (CurEntry.Contributions[Index].Length = Pair.second);
  557. }
  558. uint32_t &InfoSectionOffset =
  559. ContributionOffsets[getContributionIndex(DW_SECT_INFO, IndexVersion)];
  560. if (CurCUIndexSection.empty()) {
  561. bool FoundCUUnit = false;
  562. Out.SwitchSection(InfoSection);
  563. for (StringRef Info : CurInfoSection) {
  564. uint64_t UnitOffset = 0;
  565. while (Info.size() > UnitOffset) {
  566. Expected<InfoSectionUnitHeader> HeaderOrError =
  567. parseInfoSectionUnitHeader(Info.substr(UnitOffset, Info.size()));
  568. if (!HeaderOrError)
  569. return HeaderOrError.takeError();
  570. InfoSectionUnitHeader &Header = *HeaderOrError;
  571. UnitIndexEntry Entry = CurEntry;
  572. auto &C = Entry.Contributions[getContributionIndex(DW_SECT_INFO,
  573. IndexVersion)];
  574. C.Offset = InfoSectionOffset;
  575. C.Length = Header.Length + 4;
  576. UnitOffset += C.Length;
  577. if (Header.Version < 5 ||
  578. Header.UnitType == dwarf::DW_UT_split_compile) {
  579. Expected<CompileUnitIdentifiers> EID =
  580. getCUIdentifiers(Header, AbbrevSection,
  581. Info.substr(UnitOffset - C.Length, C.Length),
  582. CurStrOffsetSection, CurStrSection);
  583. if (!EID)
  584. return createFileError(Input, EID.takeError());
  585. const auto &ID = *EID;
  586. auto P = IndexEntries.insert(std::make_pair(ID.Signature, Entry));
  587. if (!P.second)
  588. return buildDuplicateError(*P.first, ID, "");
  589. P.first->second.Name = ID.Name;
  590. P.first->second.DWOName = ID.DWOName;
  591. FoundCUUnit = true;
  592. } else if (Header.UnitType == dwarf::DW_UT_split_type) {
  593. auto P = TypeIndexEntries.insert(
  594. std::make_pair(Header.Signature.getValue(), Entry));
  595. if (!P.second)
  596. continue;
  597. }
  598. Out.emitBytes(Info.substr(UnitOffset - C.Length, C.Length));
  599. InfoSectionOffset += C.Length;
  600. }
  601. }
  602. if (!FoundCUUnit)
  603. return make_error<DWPError>("no compile unit found in file: " + Input);
  604. if (IndexVersion == 2) {
  605. // Add types from the .debug_types section from DWARF < 5.
  606. addAllTypesFromTypesSection(
  607. Out, TypeIndexEntries, TypesSection, CurTypesSection, CurEntry,
  608. ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)]);
  609. }
  610. continue;
  611. }
  612. if (CurInfoSection.size() != 1)
  613. return make_error<DWPError>("expected exactly one occurrence of a debug "
  614. "info section in a .dwp file");
  615. StringRef DwpSingleInfoSection = CurInfoSection.front();
  616. DWARFUnitIndex CUIndex(DW_SECT_INFO);
  617. DataExtractor CUIndexData(CurCUIndexSection, Obj.isLittleEndian(), 0);
  618. if (!CUIndex.parse(CUIndexData))
  619. return make_error<DWPError>("failed to parse cu_index");
  620. if (CUIndex.getVersion() != IndexVersion)
  621. return make_error<DWPError>("incompatible cu_index versions, found " +
  622. utostr(CUIndex.getVersion()) +
  623. " and expecting " + utostr(IndexVersion));
  624. Out.SwitchSection(InfoSection);
  625. for (const DWARFUnitIndex::Entry &E : CUIndex.getRows()) {
  626. auto *I = E.getContributions();
  627. if (!I)
  628. continue;
  629. auto P = IndexEntries.insert(std::make_pair(E.getSignature(), CurEntry));
  630. StringRef CUInfoSection =
  631. getSubsection(DwpSingleInfoSection, E, DW_SECT_INFO);
  632. Expected<InfoSectionUnitHeader> HeaderOrError =
  633. parseInfoSectionUnitHeader(CUInfoSection);
  634. if (!HeaderOrError)
  635. return HeaderOrError.takeError();
  636. InfoSectionUnitHeader &Header = *HeaderOrError;
  637. Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
  638. Header, getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
  639. CUInfoSection,
  640. getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
  641. CurStrSection);
  642. if (!EID)
  643. return createFileError(Input, EID.takeError());
  644. const auto &ID = *EID;
  645. if (!P.second)
  646. return buildDuplicateError(*P.first, ID, Input);
  647. auto &NewEntry = P.first->second;
  648. NewEntry.Name = ID.Name;
  649. NewEntry.DWOName = ID.DWOName;
  650. NewEntry.DWPName = Input;
  651. for (auto Kind : CUIndex.getColumnKinds()) {
  652. if (!isSupportedSectionKind(Kind))
  653. continue;
  654. auto &C =
  655. NewEntry.Contributions[getContributionIndex(Kind, IndexVersion)];
  656. C.Offset += I->Offset;
  657. C.Length = I->Length;
  658. ++I;
  659. }
  660. unsigned Index = getContributionIndex(DW_SECT_INFO, IndexVersion);
  661. auto &C = NewEntry.Contributions[Index];
  662. Out.emitBytes(CUInfoSection);
  663. C.Offset = InfoSectionOffset;
  664. InfoSectionOffset += C.Length;
  665. }
  666. if (!CurTUIndexSection.empty()) {
  667. llvm::DWARFSectionKind TUSectionKind;
  668. MCSection *OutSection;
  669. StringRef TypeInputSection;
  670. // Write type units into debug info section for DWARFv5.
  671. if (Version >= 5) {
  672. TUSectionKind = DW_SECT_INFO;
  673. OutSection = InfoSection;
  674. TypeInputSection = DwpSingleInfoSection;
  675. } else {
  676. // Write type units into debug types section for DWARF < 5.
  677. if (CurTypesSection.size() != 1)
  678. return make_error<DWPError>(
  679. "multiple type unit sections in .dwp file");
  680. TUSectionKind = DW_SECT_EXT_TYPES;
  681. OutSection = TypesSection;
  682. TypeInputSection = CurTypesSection.front();
  683. }
  684. DWARFUnitIndex TUIndex(TUSectionKind);
  685. DataExtractor TUIndexData(CurTUIndexSection, Obj.isLittleEndian(), 0);
  686. if (!TUIndex.parse(TUIndexData))
  687. return make_error<DWPError>("failed to parse tu_index");
  688. if (TUIndex.getVersion() != IndexVersion)
  689. return make_error<DWPError>("incompatible tu_index versions, found " +
  690. utostr(TUIndex.getVersion()) +
  691. " and expecting " + utostr(IndexVersion));
  692. unsigned TypesContributionIndex =
  693. getContributionIndex(TUSectionKind, IndexVersion);
  694. addAllTypesFromDWP(Out, TypeIndexEntries, TUIndex, OutSection,
  695. TypeInputSection, CurEntry,
  696. ContributionOffsets[TypesContributionIndex],
  697. TypesContributionIndex);
  698. }
  699. }
  700. if (Version < 5) {
  701. // Lie about there being no info contributions so the TU index only includes
  702. // the type unit contribution for DWARF < 5. In DWARFv5 the TU index has a
  703. // contribution to the info section, so we do not want to lie about it.
  704. ContributionOffsets[0] = 0;
  705. }
  706. writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets,
  707. TypeIndexEntries, IndexVersion);
  708. if (Version < 5) {
  709. // Lie about the type contribution for DWARF < 5. In DWARFv5 the type
  710. // section does not exist, so no need to do anything about this.
  711. ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0;
  712. // Unlie about the info contribution
  713. ContributionOffsets[0] = 1;
  714. }
  715. writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets,
  716. IndexEntries, IndexVersion);
  717. return Error::success();
  718. }
  719. } // namespace llvm