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