DWP.cpp 31 KB

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