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