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