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