1 //===- tools/dsymutil/DwarfLinkerForBinary.cpp ----------------------------===// 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 #include "DwarfLinkerForBinary.h" 10 #include "BinaryHolder.h" 11 #include "DebugMap.h" 12 #include "MachOUtils.h" 13 #include "dsymutil.h" 14 #include "llvm/ADT/ArrayRef.h" 15 #include "llvm/ADT/BitVector.h" 16 #include "llvm/ADT/DenseMap.h" 17 #include "llvm/ADT/DenseMapInfo.h" 18 #include "llvm/ADT/DenseSet.h" 19 #include "llvm/ADT/FoldingSet.h" 20 #include "llvm/ADT/Hashing.h" 21 #include "llvm/ADT/None.h" 22 #include "llvm/ADT/Optional.h" 23 #include "llvm/ADT/PointerIntPair.h" 24 #include "llvm/ADT/STLExtras.h" 25 #include "llvm/ADT/SmallString.h" 26 #include "llvm/ADT/StringMap.h" 27 #include "llvm/ADT/StringRef.h" 28 #include "llvm/ADT/Triple.h" 29 #include "llvm/ADT/Twine.h" 30 #include "llvm/BinaryFormat/Dwarf.h" 31 #include "llvm/BinaryFormat/MachO.h" 32 #include "llvm/BinaryFormat/Swift.h" 33 #include "llvm/CodeGen/AccelTable.h" 34 #include "llvm/CodeGen/AsmPrinter.h" 35 #include "llvm/CodeGen/DIE.h" 36 #include "llvm/CodeGen/NonRelocatableStringpool.h" 37 #include "llvm/Config/config.h" 38 #include "llvm/DWARFLinker/DWARFLinkerDeclContext.h" 39 #include "llvm/DebugInfo/DIContext.h" 40 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" 41 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 42 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" 43 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" 44 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" 45 #include "llvm/DebugInfo/DWARF/DWARFDie.h" 46 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 47 #include "llvm/DebugInfo/DWARF/DWARFSection.h" 48 #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 49 #include "llvm/MC/MCAsmBackend.h" 50 #include "llvm/MC/MCAsmInfo.h" 51 #include "llvm/MC/MCCodeEmitter.h" 52 #include "llvm/MC/MCContext.h" 53 #include "llvm/MC/MCDwarf.h" 54 #include "llvm/MC/MCInstrInfo.h" 55 #include "llvm/MC/MCObjectFileInfo.h" 56 #include "llvm/MC/MCObjectWriter.h" 57 #include "llvm/MC/MCRegisterInfo.h" 58 #include "llvm/MC/MCSection.h" 59 #include "llvm/MC/MCStreamer.h" 60 #include "llvm/MC/MCSubtargetInfo.h" 61 #include "llvm/MC/MCTargetOptions.h" 62 #include "llvm/MC/MCTargetOptionsCommandFlags.h" 63 #include "llvm/MC/TargetRegistry.h" 64 #include "llvm/Object/MachO.h" 65 #include "llvm/Object/ObjectFile.h" 66 #include "llvm/Object/SymbolicFile.h" 67 #include "llvm/Support/Allocator.h" 68 #include "llvm/Support/Casting.h" 69 #include "llvm/Support/Compiler.h" 70 #include "llvm/Support/DJB.h" 71 #include "llvm/Support/DataExtractor.h" 72 #include "llvm/Support/Error.h" 73 #include "llvm/Support/ErrorHandling.h" 74 #include "llvm/Support/ErrorOr.h" 75 #include "llvm/Support/FileSystem.h" 76 #include "llvm/Support/Format.h" 77 #include "llvm/Support/LEB128.h" 78 #include "llvm/Support/MathExtras.h" 79 #include "llvm/Support/MemoryBuffer.h" 80 #include "llvm/Support/Path.h" 81 #include "llvm/Support/ThreadPool.h" 82 #include "llvm/Support/ToolOutputFile.h" 83 #include "llvm/Support/WithColor.h" 84 #include "llvm/Support/raw_ostream.h" 85 #include "llvm/Target/TargetMachine.h" 86 #include "llvm/Target/TargetOptions.h" 87 #include <algorithm> 88 #include <cassert> 89 #include <cinttypes> 90 #include <climits> 91 #include <cstdint> 92 #include <cstdlib> 93 #include <cstring> 94 #include <limits> 95 #include <map> 96 #include <memory> 97 #include <string> 98 #include <system_error> 99 #include <tuple> 100 #include <utility> 101 #include <vector> 102 103 namespace llvm { 104 105 static mc::RegisterMCTargetOptionsFlags MOF; 106 107 namespace dsymutil { 108 109 static Error copySwiftInterfaces( 110 const std::map<std::string, std::string> &ParseableSwiftInterfaces, 111 StringRef Architecture, const LinkOptions &Options) { 112 std::error_code EC; 113 SmallString<128> InputPath; 114 SmallString<128> Path; 115 sys::path::append(Path, *Options.ResourceDir, "Swift", Architecture); 116 if ((EC = sys::fs::create_directories(Path.str(), true, 117 sys::fs::perms::all_all))) 118 return make_error<StringError>( 119 "cannot create directory: " + toString(errorCodeToError(EC)), EC); 120 unsigned BaseLength = Path.size(); 121 122 for (auto &I : ParseableSwiftInterfaces) { 123 StringRef ModuleName = I.first; 124 StringRef InterfaceFile = I.second; 125 if (!Options.PrependPath.empty()) { 126 InputPath.clear(); 127 sys::path::append(InputPath, Options.PrependPath, InterfaceFile); 128 InterfaceFile = InputPath; 129 } 130 sys::path::append(Path, ModuleName); 131 Path.append(".swiftinterface"); 132 if (Options.Verbose) 133 outs() << "copy parseable Swift interface " << InterfaceFile << " -> " 134 << Path.str() << '\n'; 135 136 // copy_file attempts an APFS clone first, so this should be cheap. 137 if ((EC = sys::fs::copy_file(InterfaceFile, Path.str()))) 138 warn(Twine("cannot copy parseable Swift interface ") + InterfaceFile + 139 ": " + toString(errorCodeToError(EC))); 140 Path.resize(BaseLength); 141 } 142 return Error::success(); 143 } 144 145 /// Report a warning to the user, optionally including information about a 146 /// specific \p DIE related to the warning. 147 void DwarfLinkerForBinary::reportWarning(const Twine &Warning, 148 StringRef Context, 149 const DWARFDie *DIE) const { 150 151 warn(Warning, Context); 152 153 if (!Options.Verbose || !DIE) 154 return; 155 156 DIDumpOptions DumpOpts; 157 DumpOpts.ChildRecurseDepth = 0; 158 DumpOpts.Verbose = Options.Verbose; 159 160 WithColor::note() << " in DIE:\n"; 161 DIE->dump(errs(), 6 /* Indent */, DumpOpts); 162 } 163 164 bool DwarfLinkerForBinary::createStreamer(const Triple &TheTriple, 165 raw_fd_ostream &OutFile) { 166 if (Options.NoOutput) 167 return true; 168 169 Streamer = std::make_unique<DwarfStreamer>( 170 Options.FileType, OutFile, Options.Translator, 171 [&](const Twine &Error, StringRef Context, const DWARFDie *) { 172 error(Error, Context); 173 }, 174 [&](const Twine &Warning, StringRef Context, const DWARFDie *) { 175 warn(Warning, Context); 176 }); 177 return Streamer->init(TheTriple, "__DWARF"); 178 } 179 180 ErrorOr<const object::ObjectFile &> 181 DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj, 182 const Triple &Triple) { 183 auto ObjectEntry = 184 BinHolder.getObjectEntry(Obj.getObjectFilename(), Obj.getTimestamp()); 185 if (!ObjectEntry) { 186 auto Err = ObjectEntry.takeError(); 187 reportWarning(Twine(Obj.getObjectFilename()) + ": " + 188 toString(std::move(Err)), 189 Obj.getObjectFilename()); 190 return errorToErrorCode(std::move(Err)); 191 } 192 193 auto Object = ObjectEntry->getObject(Triple); 194 if (!Object) { 195 auto Err = Object.takeError(); 196 reportWarning(Twine(Obj.getObjectFilename()) + ": " + 197 toString(std::move(Err)), 198 Obj.getObjectFilename()); 199 return errorToErrorCode(std::move(Err)); 200 } 201 202 return *Object; 203 } 204 205 static Error remarksErrorHandler(const DebugMapObject &DMO, 206 DwarfLinkerForBinary &Linker, 207 std::unique_ptr<FileError> FE) { 208 bool IsArchive = DMO.getObjectFilename().endswith(")"); 209 // Don't report errors for missing remark files from static 210 // archives. 211 if (!IsArchive) 212 return Error(std::move(FE)); 213 214 std::string Message = FE->message(); 215 Error E = FE->takeError(); 216 Error NewE = handleErrors(std::move(E), [&](std::unique_ptr<ECError> EC) { 217 if (EC->convertToErrorCode() != std::errc::no_such_file_or_directory) 218 return Error(std::move(EC)); 219 220 Linker.reportWarning(Message, DMO.getObjectFilename()); 221 return Error(Error::success()); 222 }); 223 224 if (!NewE) 225 return Error::success(); 226 227 return createFileError(FE->getFileName(), std::move(NewE)); 228 } 229 230 static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath, 231 StringRef ArchName, const remarks::RemarkLinker &RL) { 232 // Make sure we don't create the directories and the file if there is nothing 233 // to serialize. 234 if (RL.empty()) 235 return Error::success(); 236 237 SmallString<128> InputPath; 238 SmallString<128> Path; 239 // Create the "Remarks" directory in the "Resources" directory. 240 sys::path::append(Path, *Options.ResourceDir, "Remarks"); 241 if (std::error_code EC = sys::fs::create_directories(Path.str(), true, 242 sys::fs::perms::all_all)) 243 return errorCodeToError(EC); 244 245 // Append the file name. 246 // For fat binaries, also append a dash and the architecture name. 247 sys::path::append(Path, sys::path::filename(BinaryPath)); 248 if (Options.NumDebugMaps > 1) { 249 // More than one debug map means we have a fat binary. 250 Path += '-'; 251 Path += ArchName; 252 } 253 254 std::error_code EC; 255 raw_fd_ostream OS(Options.NoOutput ? "-" : Path.str(), EC, 256 Options.RemarksFormat == remarks::Format::Bitstream 257 ? sys::fs::OF_None 258 : sys::fs::OF_Text); 259 if (EC) 260 return errorCodeToError(EC); 261 262 if (Error E = RL.serialize(OS, Options.RemarksFormat)) 263 return E; 264 265 return Error::success(); 266 } 267 268 ErrorOr<DWARFFile &> 269 DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj, 270 const DebugMap &DebugMap, 271 remarks::RemarkLinker &RL) { 272 auto ErrorOrObj = loadObject(Obj, DebugMap.getTriple()); 273 274 if (ErrorOrObj) { 275 ContextForLinking.push_back( 276 std::unique_ptr<DWARFContext>(DWARFContext::create(*ErrorOrObj))); 277 AddressMapForLinking.push_back( 278 std::make_unique<AddressManager>(*this, *ErrorOrObj, Obj)); 279 280 ObjectsForLinking.push_back(std::make_unique<DWARFFile>( 281 Obj.getObjectFilename(), ContextForLinking.back().get(), 282 AddressMapForLinking.back().get(), 283 Obj.empty() ? Obj.getWarnings() : EmptyWarnings)); 284 285 Error E = RL.link(*ErrorOrObj); 286 if (Error NewE = handleErrors( 287 std::move(E), [&](std::unique_ptr<FileError> EC) -> Error { 288 return remarksErrorHandler(Obj, *this, std::move(EC)); 289 })) 290 return errorToErrorCode(std::move(NewE)); 291 292 return *ObjectsForLinking.back(); 293 } 294 295 return ErrorOrObj.getError(); 296 } 297 298 static bool binaryHasStrippableSwiftReflectionSections( 299 const DebugMap &Map, const LinkOptions &Options, BinaryHolder &BinHolder) { 300 // If the input binary has strippable swift5 reflection sections, there is no 301 // need to copy them to the .dSYM. Only copy them for binaries where the 302 // linker omitted the reflection metadata. 303 if (!Map.getBinaryPath().empty() && 304 Options.FileType == OutputFileType::Object) { 305 306 auto ObjectEntry = BinHolder.getObjectEntry(Map.getBinaryPath()); 307 // If ObjectEntry or Object has an error, no binary exists, therefore no 308 // reflection sections exist. 309 if (!ObjectEntry) { 310 // Any errors will be diagnosed later in the main loop, ignore them here. 311 llvm::consumeError(ObjectEntry.takeError()); 312 return false; 313 } 314 315 auto Object = 316 ObjectEntry->getObjectAs<object::MachOObjectFile>(Map.getTriple()); 317 if (!Object) { 318 // Any errors will be diagnosed later in the main loop, ignore them here. 319 llvm::consumeError(Object.takeError()); 320 return false; 321 } 322 323 for (auto &Section : Object->sections()) { 324 llvm::Expected<llvm::StringRef> NameOrErr = 325 Object->getSectionName(Section.getRawDataRefImpl()); 326 if (!NameOrErr) { 327 llvm::consumeError(NameOrErr.takeError()); 328 continue; 329 } 330 NameOrErr->consume_back("__TEXT"); 331 auto ReflectionSectionKind = 332 Object->mapReflectionSectionNameToEnumValue(*NameOrErr); 333 if (Object->isReflectionSectionStrippable(ReflectionSectionKind)) { 334 return true; 335 } 336 } 337 } 338 return false; 339 } 340 341 /// Calculate the start of the strippable swift reflection sections in Dwarf. 342 /// Note that there's an assumption that the reflection sections will appear 343 /// in alphabetic order. 344 static std::vector<uint64_t> 345 calculateStartOfStrippableReflectionSections(const DebugMap &Map) { 346 using llvm::binaryformat::Swift5ReflectionSectionKind; 347 uint64_t AssocTySize = 0; 348 uint64_t FieldMdSize = 0; 349 for (const auto &Obj : Map.objects()) { 350 auto OF = 351 llvm::object::ObjectFile::createObjectFile(Obj->getObjectFilename()); 352 if (!OF) { 353 llvm::consumeError(OF.takeError()); 354 continue; 355 } 356 if (auto *MO = dyn_cast<llvm::object::MachOObjectFile>(OF->getBinary())) { 357 for (auto &Section : MO->sections()) { 358 llvm::Expected<llvm::StringRef> NameOrErr = 359 MO->getSectionName(Section.getRawDataRefImpl()); 360 if (!NameOrErr) { 361 llvm::consumeError(NameOrErr.takeError()); 362 continue; 363 } 364 NameOrErr->consume_back("__TEXT"); 365 auto ReflSectionKind = 366 MO->mapReflectionSectionNameToEnumValue(*NameOrErr); 367 switch (ReflSectionKind) { 368 case Swift5ReflectionSectionKind::assocty: 369 AssocTySize += Section.getSize(); 370 break; 371 case Swift5ReflectionSectionKind::fieldmd: 372 FieldMdSize += Section.getSize(); 373 break; 374 default: 375 break; 376 } 377 } 378 } 379 } 380 // Initialize the vector with enough space to fit every reflection section 381 // kind. 382 std::vector<uint64_t> SectionToOffset(Swift5ReflectionSectionKind::last, 0); 383 SectionToOffset[Swift5ReflectionSectionKind::assocty] = 0; 384 SectionToOffset[Swift5ReflectionSectionKind::fieldmd] = 385 llvm::alignTo(AssocTySize, 4); 386 SectionToOffset[Swift5ReflectionSectionKind::reflstr] = llvm::alignTo( 387 SectionToOffset[Swift5ReflectionSectionKind::fieldmd] + FieldMdSize, 4); 388 389 return SectionToOffset; 390 } 391 392 void DwarfLinkerForBinary::collectRelocationsToApplyToSwiftReflectionSections( 393 const object::SectionRef &Section, StringRef &Contents, 394 const llvm::object::MachOObjectFile *MO, 395 const std::vector<uint64_t> &SectionToOffsetInDwarf, 396 const llvm::dsymutil::DebugMapObject *Obj, 397 std::vector<MachOUtils::DwarfRelocationApplicationInfo> &RelocationsToApply) 398 const { 399 for (auto It = Section.relocation_begin(); It != Section.relocation_end(); 400 ++It) { 401 object::DataRefImpl RelocDataRef = It->getRawDataRefImpl(); 402 MachO::any_relocation_info MachOReloc = MO->getRelocation(RelocDataRef); 403 404 if (!object::MachOObjectFile::isMachOPairedReloc( 405 MO->getAnyRelocationType(MachOReloc), MO->getArch())) { 406 reportWarning( 407 "Unimplemented relocation type in strippable reflection section ", 408 Obj->getObjectFilename()); 409 continue; 410 } 411 412 auto CalculateAddressOfSymbolInDwarfSegment = 413 [&]() -> llvm::Optional<int64_t> { 414 auto Symbol = It->getSymbol(); 415 auto SymbolAbsoluteAddress = Symbol->getAddress(); 416 if (!SymbolAbsoluteAddress) 417 return {}; 418 auto Section = Symbol->getSection(); 419 if (!Section) { 420 llvm::consumeError(Section.takeError()); 421 return {}; 422 } 423 424 if ((*Section)->getObject()->section_end() == *Section) 425 return {}; 426 427 auto SectionStart = (*Section)->getAddress(); 428 auto SymbolAddressInSection = *SymbolAbsoluteAddress - SectionStart; 429 auto SectionName = (*Section)->getName(); 430 if (!SectionName) 431 return {}; 432 auto ReflSectionKind = 433 MO->mapReflectionSectionNameToEnumValue(*SectionName); 434 435 int64_t SectionStartInLinkedBinary = 436 SectionToOffsetInDwarf[ReflSectionKind]; 437 438 auto Addr = SectionStartInLinkedBinary + SymbolAddressInSection; 439 return Addr; 440 }; 441 442 // The first symbol should always be in the section we're currently 443 // iterating over. 444 auto FirstSymbolAddress = CalculateAddressOfSymbolInDwarfSegment(); 445 ++It; 446 447 bool ShouldSubtractDwarfVM = false; 448 // For the second symbol there are two possibilities. 449 llvm::Optional<int64_t> SecondSymbolAddress; 450 auto Sym = It->getSymbol(); 451 if (Sym != MO->symbol_end()) { 452 Expected<StringRef> SymbolName = Sym->getName(); 453 if (SymbolName) { 454 if (const auto *Mapping = Obj->lookupSymbol(*SymbolName)) { 455 // First possibility: the symbol exists in the binary, and exists in a 456 // non-strippable section (for example, typeref, or __TEXT,__const), 457 // in which case we look up its address in the binary, which dsymutil 458 // will copy verbatim. 459 SecondSymbolAddress = Mapping->getValue().BinaryAddress; 460 // Since the symbols live in different segments, we have to substract 461 // the start of the Dwarf's vmaddr so the value calculated points to 462 // the correct place. 463 ShouldSubtractDwarfVM = true; 464 } 465 } 466 } 467 468 if (!SecondSymbolAddress) { 469 // Second possibility, this symbol is not present in the main binary, and 470 // must be in one of the strippable sections (for example, reflstr). 471 // Calculate its address in the same way as we did the first one. 472 SecondSymbolAddress = CalculateAddressOfSymbolInDwarfSegment(); 473 } 474 475 if (!FirstSymbolAddress || !SecondSymbolAddress) 476 continue; 477 478 auto SectionName = Section.getName(); 479 if (!SectionName) 480 continue; 481 482 int32_t Addend; 483 memcpy(&Addend, Contents.data() + It->getOffset(), sizeof(int32_t)); 484 int32_t Value = (*SecondSymbolAddress + Addend) - *FirstSymbolAddress; 485 auto ReflSectionKind = 486 MO->mapReflectionSectionNameToEnumValue(*SectionName); 487 uint64_t AddressFromDwarfVM = 488 SectionToOffsetInDwarf[ReflSectionKind] + It->getOffset(); 489 RelocationsToApply.emplace_back(AddressFromDwarfVM, Value, 490 ShouldSubtractDwarfVM); 491 } 492 } 493 494 void DwarfLinkerForBinary::copySwiftReflectionMetadata( 495 const llvm::dsymutil::DebugMapObject *Obj, DwarfStreamer *Streamer, 496 std::vector<uint64_t> &SectionToOffsetInDwarf, 497 std::vector<MachOUtils::DwarfRelocationApplicationInfo> 498 &RelocationsToApply) { 499 using binaryformat::Swift5ReflectionSectionKind; 500 auto OF = 501 llvm::object::ObjectFile::createObjectFile(Obj->getObjectFilename()); 502 if (!OF) { 503 llvm::consumeError(OF.takeError()); 504 return; 505 } 506 if (auto *MO = dyn_cast<llvm::object::MachOObjectFile>(OF->getBinary())) { 507 // Collect the swift reflection sections before emitting them. This is 508 // done so we control the order they're emitted. 509 std::array<Optional<object::SectionRef>, 510 Swift5ReflectionSectionKind::last + 1> 511 SwiftSections; 512 for (auto &Section : MO->sections()) { 513 llvm::Expected<llvm::StringRef> NameOrErr = 514 MO->getSectionName(Section.getRawDataRefImpl()); 515 if (!NameOrErr) { 516 llvm::consumeError(NameOrErr.takeError()); 517 continue; 518 } 519 NameOrErr->consume_back("__TEXT"); 520 auto ReflSectionKind = 521 MO->mapReflectionSectionNameToEnumValue(*NameOrErr); 522 if (MO->isReflectionSectionStrippable(ReflSectionKind)) 523 SwiftSections[ReflSectionKind] = Section; 524 } 525 // Make sure we copy the sections in alphabetic order. 526 auto SectionKindsToEmit = {Swift5ReflectionSectionKind::assocty, 527 Swift5ReflectionSectionKind::fieldmd, 528 Swift5ReflectionSectionKind::reflstr}; 529 for (auto SectionKind : SectionKindsToEmit) { 530 if (!SwiftSections[SectionKind]) 531 continue; 532 auto &Section = *SwiftSections[SectionKind]; 533 llvm::Expected<llvm::StringRef> SectionContents = Section.getContents(); 534 if (!SectionContents) 535 continue; 536 const auto *MO = 537 llvm::cast<llvm::object::MachOObjectFile>(Section.getObject()); 538 collectRelocationsToApplyToSwiftReflectionSections( 539 Section, *SectionContents, MO, SectionToOffsetInDwarf, Obj, 540 RelocationsToApply); 541 // Update the section start with the current section's contribution, so 542 // the next section we copy from a different .o file points to the correct 543 // place. 544 SectionToOffsetInDwarf[SectionKind] += Section.getSize(); 545 Streamer->emitSwiftReflectionSection(SectionKind, *SectionContents, 546 Section.getAlignment(), 547 Section.getSize()); 548 } 549 } 550 } 551 552 bool DwarfLinkerForBinary::link(const DebugMap &Map) { 553 if (!createStreamer(Map.getTriple(), OutFile)) 554 return false; 555 556 ObjectsForLinking.clear(); 557 ContextForLinking.clear(); 558 AddressMapForLinking.clear(); 559 560 DebugMap DebugMap(Map.getTriple(), Map.getBinaryPath()); 561 562 DWARFLinker GeneralLinker(Streamer.get(), DwarfLinkerClient::Dsymutil); 563 564 remarks::RemarkLinker RL; 565 if (!Options.RemarksPrependPath.empty()) 566 RL.setExternalFilePrependPath(Options.RemarksPrependPath); 567 GeneralLinker.setObjectPrefixMap(&Options.ObjectPrefixMap); 568 569 std::function<StringRef(StringRef)> TranslationLambda = [&](StringRef Input) { 570 assert(Options.Translator); 571 return Options.Translator(Input); 572 }; 573 574 GeneralLinker.setVerbosity(Options.Verbose); 575 GeneralLinker.setStatistics(Options.Statistics); 576 GeneralLinker.setVerifyInputDWARF(Options.VerifyInputDWARF); 577 GeneralLinker.setNoOutput(Options.NoOutput); 578 GeneralLinker.setNoODR(Options.NoODR); 579 GeneralLinker.setUpdate(Options.Update); 580 GeneralLinker.setNumThreads(Options.Threads); 581 GeneralLinker.setAccelTableKind(Options.TheAccelTableKind); 582 GeneralLinker.setPrependPath(Options.PrependPath); 583 GeneralLinker.setKeepFunctionForStatic(Options.KeepFunctionForStatic); 584 if (Options.Translator) 585 GeneralLinker.setStringsTranslator(TranslationLambda); 586 GeneralLinker.setWarningHandler( 587 [&](const Twine &Warning, StringRef Context, const DWARFDie *DIE) { 588 reportWarning(Warning, Context, DIE); 589 }); 590 GeneralLinker.setErrorHandler( 591 [&](const Twine &Error, StringRef Context, const DWARFDie *) { 592 error(Error, Context); 593 }); 594 GeneralLinker.setObjFileLoader( 595 [&DebugMap, &RL, this](StringRef ContainerName, 596 StringRef Path) -> ErrorOr<DWARFFile &> { 597 auto &Obj = DebugMap.addDebugMapObject( 598 Path, sys::TimePoint<std::chrono::seconds>(), MachO::N_OSO); 599 600 if (auto ErrorOrObj = loadObject(Obj, DebugMap, RL)) { 601 return *ErrorOrObj; 602 } else { 603 // Try and emit more helpful warnings by applying some heuristics. 604 StringRef ObjFile = ContainerName; 605 bool IsClangModule = sys::path::extension(Path).equals(".pcm"); 606 bool IsArchive = ObjFile.endswith(")"); 607 608 if (IsClangModule) { 609 StringRef ModuleCacheDir = sys::path::parent_path(Path); 610 if (sys::fs::exists(ModuleCacheDir)) { 611 // If the module's parent directory exists, we assume that the 612 // module cache has expired and was pruned by clang. A more 613 // adventurous dsymutil would invoke clang to rebuild the module 614 // now. 615 if (!ModuleCacheHintDisplayed) { 616 WithColor::note() 617 << "The clang module cache may have expired since " 618 "this object file was built. Rebuilding the " 619 "object file will rebuild the module cache.\n"; 620 ModuleCacheHintDisplayed = true; 621 } 622 } else if (IsArchive) { 623 // If the module cache directory doesn't exist at all and the 624 // object file is inside a static library, we assume that the 625 // static library was built on a different machine. We don't want 626 // to discourage module debugging for convenience libraries within 627 // a project though. 628 if (!ArchiveHintDisplayed) { 629 WithColor::note() 630 << "Linking a static library that was built with " 631 "-gmodules, but the module cache was not found. " 632 "Redistributable static libraries should never be " 633 "built with module debugging enabled. The debug " 634 "experience will be degraded due to incomplete " 635 "debug information.\n"; 636 ArchiveHintDisplayed = true; 637 } 638 } 639 } 640 641 return ErrorOrObj.getError(); 642 } 643 644 llvm_unreachable("Unhandled DebugMap object"); 645 }); 646 GeneralLinker.setSwiftInterfacesMap(&ParseableSwiftInterfaces); 647 bool ReflectionSectionsPresentInBinary = false; 648 // If there is no output specified, no point in checking the binary for swift5 649 // reflection sections. 650 if (!Options.NoOutput) { 651 ReflectionSectionsPresentInBinary = 652 binaryHasStrippableSwiftReflectionSections(Map, Options, BinHolder); 653 } 654 655 std::vector<MachOUtils::DwarfRelocationApplicationInfo> RelocationsToApply; 656 if (!Options.NoOutput && !ReflectionSectionsPresentInBinary) { 657 auto SectionToOffsetInDwarf = 658 calculateStartOfStrippableReflectionSections(Map); 659 for (const auto &Obj : Map.objects()) 660 copySwiftReflectionMetadata(Obj.get(), Streamer.get(), 661 SectionToOffsetInDwarf, RelocationsToApply); 662 } 663 664 for (const auto &Obj : Map.objects()) { 665 // N_AST objects (swiftmodule files) should get dumped directly into the 666 // appropriate DWARF section. 667 if (Obj->getType() == MachO::N_AST) { 668 if (Options.Verbose) 669 outs() << "DEBUG MAP OBJECT: " << Obj->getObjectFilename() << "\n"; 670 671 StringRef File = Obj->getObjectFilename(); 672 auto ErrorOrMem = MemoryBuffer::getFile(File); 673 if (!ErrorOrMem) { 674 warn("Could not open '" + File + "'\n"); 675 continue; 676 } 677 sys::fs::file_status Stat; 678 if (auto Err = sys::fs::status(File, Stat)) { 679 warn(Err.message()); 680 continue; 681 } 682 if (!Options.NoTimestamp) { 683 // The modification can have sub-second precision so we need to cast 684 // away the extra precision that's not present in the debug map. 685 auto ModificationTime = 686 std::chrono::time_point_cast<std::chrono::seconds>( 687 Stat.getLastModificationTime()); 688 if (Obj->getTimestamp() != sys::TimePoint<>() && 689 ModificationTime != Obj->getTimestamp()) { 690 // Not using the helper here as we can easily stream TimePoint<>. 691 WithColor::warning() 692 << File << ": timestamp mismatch between swift interface file (" 693 << sys::TimePoint<>(ModificationTime) << ") and debug map (" 694 << sys::TimePoint<>(Obj->getTimestamp()) << ")\n"; 695 continue; 696 } 697 } 698 699 // Copy the module into the .swift_ast section. 700 if (!Options.NoOutput) 701 Streamer->emitSwiftAST((*ErrorOrMem)->getBuffer()); 702 703 continue; 704 } 705 if (auto ErrorOrObj = loadObject(*Obj, Map, RL)) 706 GeneralLinker.addObjectFile(*ErrorOrObj); 707 else { 708 ObjectsForLinking.push_back(std::make_unique<DWARFFile>( 709 Obj->getObjectFilename(), nullptr, nullptr, 710 Obj->empty() ? Obj->getWarnings() : EmptyWarnings)); 711 GeneralLinker.addObjectFile(*ObjectsForLinking.back()); 712 } 713 } 714 715 // link debug info for loaded object files. 716 GeneralLinker.link(); 717 718 StringRef ArchName = Map.getTriple().getArchName(); 719 if (Error E = emitRemarks(Options, Map.getBinaryPath(), ArchName, RL)) 720 return error(toString(std::move(E))); 721 722 if (Options.NoOutput) 723 return true; 724 725 if (Options.ResourceDir && !ParseableSwiftInterfaces.empty()) { 726 StringRef ArchName = Triple::getArchTypeName(Map.getTriple().getArch()); 727 if (auto E = 728 copySwiftInterfaces(ParseableSwiftInterfaces, ArchName, Options)) 729 return error(toString(std::move(E))); 730 } 731 732 if (Map.getTriple().isOSDarwin() && !Map.getBinaryPath().empty() && 733 Options.FileType == OutputFileType::Object) 734 return MachOUtils::generateDsymCompanion( 735 Options.VFS, Map, Options.Translator, 736 *Streamer->getAsmPrinter().OutStreamer, OutFile, RelocationsToApply); 737 738 Streamer->finish(); 739 return true; 740 } 741 742 /// Iterate over the relocations of the given \p Section and 743 /// store the ones that correspond to debug map entries into the 744 /// ValidRelocs array. 745 void DwarfLinkerForBinary::AddressManager::findValidRelocsMachO( 746 const object::SectionRef &Section, const object::MachOObjectFile &Obj, 747 const DebugMapObject &DMO, std::vector<ValidReloc> &ValidRelocs) { 748 Expected<StringRef> ContentsOrErr = Section.getContents(); 749 if (!ContentsOrErr) { 750 consumeError(ContentsOrErr.takeError()); 751 Linker.reportWarning("error reading section", DMO.getObjectFilename()); 752 return; 753 } 754 DataExtractor Data(*ContentsOrErr, Obj.isLittleEndian(), 0); 755 bool SkipNext = false; 756 757 for (const object::RelocationRef &Reloc : Section.relocations()) { 758 if (SkipNext) { 759 SkipNext = false; 760 continue; 761 } 762 763 object::DataRefImpl RelocDataRef = Reloc.getRawDataRefImpl(); 764 MachO::any_relocation_info MachOReloc = Obj.getRelocation(RelocDataRef); 765 766 if (object::MachOObjectFile::isMachOPairedReloc(Obj.getAnyRelocationType(MachOReloc), 767 Obj.getArch())) { 768 SkipNext = true; 769 Linker.reportWarning("unsupported relocation in " + *Section.getName() + 770 " section.", 771 DMO.getObjectFilename()); 772 continue; 773 } 774 775 unsigned RelocSize = 1 << Obj.getAnyRelocationLength(MachOReloc); 776 uint64_t Offset64 = Reloc.getOffset(); 777 if ((RelocSize != 4 && RelocSize != 8)) { 778 Linker.reportWarning("unsupported relocation in " + *Section.getName() + 779 " section.", 780 DMO.getObjectFilename()); 781 continue; 782 } 783 uint64_t OffsetCopy = Offset64; 784 // Mach-o uses REL relocations, the addend is at the relocation offset. 785 uint64_t Addend = Data.getUnsigned(&OffsetCopy, RelocSize); 786 uint64_t SymAddress; 787 int64_t SymOffset; 788 789 if (Obj.isRelocationScattered(MachOReloc)) { 790 // The address of the base symbol for scattered relocations is 791 // stored in the reloc itself. The actual addend will store the 792 // base address plus the offset. 793 SymAddress = Obj.getScatteredRelocationValue(MachOReloc); 794 SymOffset = int64_t(Addend) - SymAddress; 795 } else { 796 SymAddress = Addend; 797 SymOffset = 0; 798 } 799 800 auto Sym = Reloc.getSymbol(); 801 if (Sym != Obj.symbol_end()) { 802 Expected<StringRef> SymbolName = Sym->getName(); 803 if (!SymbolName) { 804 consumeError(SymbolName.takeError()); 805 Linker.reportWarning("error getting relocation symbol name.", 806 DMO.getObjectFilename()); 807 continue; 808 } 809 if (const auto *Mapping = DMO.lookupSymbol(*SymbolName)) 810 ValidRelocs.emplace_back(Offset64, RelocSize, Addend, Mapping); 811 } else if (const auto *Mapping = DMO.lookupObjectAddress(SymAddress)) { 812 // Do not store the addend. The addend was the address of the symbol in 813 // the object file, the address in the binary that is stored in the debug 814 // map doesn't need to be offset. 815 ValidRelocs.emplace_back(Offset64, RelocSize, SymOffset, Mapping); 816 } 817 } 818 } 819 820 /// Dispatch the valid relocation finding logic to the 821 /// appropriate handler depending on the object file format. 822 bool DwarfLinkerForBinary::AddressManager::findValidRelocs( 823 const object::SectionRef &Section, const object::ObjectFile &Obj, 824 const DebugMapObject &DMO, std::vector<ValidReloc> &Relocs) { 825 // Dispatch to the right handler depending on the file type. 826 if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(&Obj)) 827 findValidRelocsMachO(Section, *MachOObj, DMO, Relocs); 828 else 829 Linker.reportWarning(Twine("unsupported object file type: ") + 830 Obj.getFileName(), 831 DMO.getObjectFilename()); 832 if (Relocs.empty()) 833 return false; 834 835 // Sort the relocations by offset. We will walk the DIEs linearly in 836 // the file, this allows us to just keep an index in the relocation 837 // array that we advance during our walk, rather than resorting to 838 // some associative container. See DwarfLinkerForBinary::NextValidReloc. 839 llvm::sort(Relocs); 840 return true; 841 } 842 843 /// Look for relocations in the debug_info and debug_addr section that match 844 /// entries in the debug map. These relocations will drive the Dwarf link by 845 /// indicating which DIEs refer to symbols present in the linked binary. 846 /// \returns whether there are any valid relocations in the debug info. 847 bool DwarfLinkerForBinary::AddressManager::findValidRelocsInDebugSections( 848 const object::ObjectFile &Obj, const DebugMapObject &DMO) { 849 // Find the debug_info section. 850 bool FoundValidRelocs = false; 851 for (const object::SectionRef &Section : Obj.sections()) { 852 StringRef SectionName; 853 if (Expected<StringRef> NameOrErr = Section.getName()) 854 SectionName = *NameOrErr; 855 else 856 consumeError(NameOrErr.takeError()); 857 858 SectionName = SectionName.substr(SectionName.find_first_not_of("._")); 859 if (SectionName == "debug_info") 860 FoundValidRelocs |= 861 findValidRelocs(Section, Obj, DMO, ValidDebugInfoRelocs); 862 if (SectionName == "debug_addr") 863 FoundValidRelocs |= 864 findValidRelocs(Section, Obj, DMO, ValidDebugAddrRelocs); 865 } 866 return FoundValidRelocs; 867 } 868 869 std::vector<DwarfLinkerForBinary::AddressManager::ValidReloc> 870 DwarfLinkerForBinary::AddressManager::getRelocations( 871 const std::vector<ValidReloc> &Relocs, uint64_t StartPos, uint64_t EndPos) { 872 std::vector<DwarfLinkerForBinary::AddressManager::ValidReloc> Res; 873 874 auto CurReloc = partition_point(Relocs, [StartPos](const ValidReloc &Reloc) { 875 return Reloc.Offset < StartPos; 876 }); 877 878 while (CurReloc != Relocs.end() && CurReloc->Offset >= StartPos && 879 CurReloc->Offset < EndPos) { 880 Res.push_back(*CurReloc); 881 CurReloc++; 882 } 883 884 return Res; 885 } 886 887 void DwarfLinkerForBinary::AddressManager::printReloc(const ValidReloc &Reloc) { 888 const auto &Mapping = Reloc.Mapping->getValue(); 889 const uint64_t ObjectAddress = Mapping.ObjectAddress 890 ? uint64_t(*Mapping.ObjectAddress) 891 : std::numeric_limits<uint64_t>::max(); 892 893 outs() << "Found valid debug map entry: " << Reloc.Mapping->getKey() << "\t" 894 << format("0x%016" PRIx64 " => 0x%016" PRIx64 "\n", ObjectAddress, 895 uint64_t(Mapping.BinaryAddress)); 896 } 897 898 void DwarfLinkerForBinary::AddressManager::fillDieInfo( 899 const ValidReloc &Reloc, CompileUnit::DIEInfo &Info) { 900 Info.AddrAdjust = relocate(Reloc); 901 if (Reloc.Mapping->getValue().ObjectAddress) 902 Info.AddrAdjust -= uint64_t(*Reloc.Mapping->getValue().ObjectAddress); 903 Info.InDebugMap = true; 904 } 905 906 bool DwarfLinkerForBinary::AddressManager::hasValidRelocationAt( 907 const std::vector<ValidReloc> &AllRelocs, uint64_t StartOffset, 908 uint64_t EndOffset, CompileUnit::DIEInfo &Info) { 909 std::vector<ValidReloc> Relocs = 910 getRelocations(AllRelocs, StartOffset, EndOffset); 911 912 if (Relocs.size() == 0) 913 return false; 914 915 if (Linker.Options.Verbose) 916 printReloc(Relocs[0]); 917 fillDieInfo(Relocs[0], Info); 918 919 return true; 920 } 921 922 /// Get the starting and ending (exclusive) offset for the 923 /// attribute with index \p Idx descibed by \p Abbrev. \p Offset is 924 /// supposed to point to the position of the first attribute described 925 /// by \p Abbrev. 926 /// \return [StartOffset, EndOffset) as a pair. 927 static std::pair<uint64_t, uint64_t> 928 getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx, 929 uint64_t Offset, const DWARFUnit &Unit) { 930 DataExtractor Data = Unit.getDebugInfoExtractor(); 931 932 for (unsigned I = 0; I < Idx; ++I) 933 DWARFFormValue::skipValue(Abbrev->getFormByIndex(I), Data, &Offset, 934 Unit.getFormParams()); 935 936 uint64_t End = Offset; 937 DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End, 938 Unit.getFormParams()); 939 940 return std::make_pair(Offset, End); 941 } 942 943 bool DwarfLinkerForBinary::AddressManager::isLiveVariable( 944 const DWARFDie &DIE, CompileUnit::DIEInfo &MyInfo) { 945 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); 946 947 Optional<uint32_t> LocationIdx = 948 Abbrev->findAttributeIndex(dwarf::DW_AT_location); 949 if (!LocationIdx) 950 return false; 951 952 uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode()); 953 uint64_t LocationOffset, LocationEndOffset; 954 std::tie(LocationOffset, LocationEndOffset) = 955 getAttributeOffsets(Abbrev, *LocationIdx, Offset, *DIE.getDwarfUnit()); 956 957 // FIXME: Support relocations debug_addr. 958 return hasValidRelocationAt(ValidDebugInfoRelocs, LocationOffset, 959 LocationEndOffset, MyInfo); 960 } 961 962 bool DwarfLinkerForBinary::AddressManager::isLiveSubprogram( 963 const DWARFDie &DIE, CompileUnit::DIEInfo &MyInfo) { 964 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); 965 966 Optional<uint32_t> LowPcIdx = Abbrev->findAttributeIndex(dwarf::DW_AT_low_pc); 967 if (!LowPcIdx) 968 return false; 969 970 dwarf::Form Form = Abbrev->getFormByIndex(*LowPcIdx); 971 972 if (Form == dwarf::DW_FORM_addr) { 973 uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode()); 974 uint64_t LowPcOffset, LowPcEndOffset; 975 std::tie(LowPcOffset, LowPcEndOffset) = 976 getAttributeOffsets(Abbrev, *LowPcIdx, Offset, *DIE.getDwarfUnit()); 977 return hasValidRelocationAt(ValidDebugInfoRelocs, LowPcOffset, 978 LowPcEndOffset, MyInfo); 979 } 980 981 if (Form == dwarf::DW_FORM_addrx) { 982 Optional<DWARFFormValue> AddrValue = DIE.find(dwarf::DW_AT_low_pc); 983 if (Optional<uint64_t> AddrOffsetSectionBase = 984 DIE.getDwarfUnit()->getAddrOffsetSectionBase()) { 985 uint64_t StartOffset = *AddrOffsetSectionBase + AddrValue->getRawUValue(); 986 uint64_t EndOffset = 987 StartOffset + DIE.getDwarfUnit()->getAddressByteSize(); 988 return hasValidRelocationAt(ValidDebugAddrRelocs, StartOffset, EndOffset, 989 MyInfo); 990 } else 991 Linker.reportWarning("no base offset for address table", SrcFileName); 992 } 993 994 return false; 995 } 996 997 uint64_t 998 DwarfLinkerForBinary::AddressManager::relocate(const ValidReloc &Reloc) const { 999 return Reloc.Mapping->getValue().BinaryAddress + Reloc.Addend; 1000 } 1001 1002 /// Apply the valid relocations found by findValidRelocs() to 1003 /// the buffer \p Data, taking into account that Data is at \p BaseOffset 1004 /// in the debug_info section. 1005 /// 1006 /// Like for findValidRelocs(), this function must be called with 1007 /// monotonic \p BaseOffset values. 1008 /// 1009 /// \returns whether any reloc has been applied. 1010 bool DwarfLinkerForBinary::AddressManager::applyValidRelocs( 1011 MutableArrayRef<char> Data, uint64_t BaseOffset, bool IsLittleEndian) { 1012 std::vector<ValidReloc> Relocs = getRelocations( 1013 ValidDebugInfoRelocs, BaseOffset, BaseOffset + Data.size()); 1014 1015 for (const ValidReloc &CurReloc : Relocs) { 1016 assert(CurReloc.Offset - BaseOffset < Data.size()); 1017 assert(CurReloc.Offset - BaseOffset + CurReloc.Size <= Data.size()); 1018 char Buf[8]; 1019 uint64_t Value = relocate(CurReloc); 1020 for (unsigned I = 0; I != CurReloc.Size; ++I) { 1021 unsigned Index = IsLittleEndian ? I : (CurReloc.Size - I - 1); 1022 Buf[I] = uint8_t(Value >> (Index * 8)); 1023 } 1024 assert(CurReloc.Size <= sizeof(Buf)); 1025 memcpy(&Data[CurReloc.Offset - BaseOffset], Buf, CurReloc.Size); 1026 } 1027 1028 return Relocs.size() > 0; 1029 } 1030 1031 llvm::Expected<uint64_t> 1032 DwarfLinkerForBinary::AddressManager::relocateIndexedAddr(uint64_t StartOffset, 1033 uint64_t EndOffset) { 1034 std::vector<ValidReloc> Relocs = 1035 getRelocations(ValidDebugAddrRelocs, StartOffset, EndOffset); 1036 if (Relocs.size() == 0) 1037 return createStringError( 1038 std::make_error_code(std::errc::invalid_argument), 1039 "no relocation for offset %llu in debug_addr section", StartOffset); 1040 1041 return relocate(Relocs[0]); 1042 } 1043 1044 bool linkDwarf(raw_fd_ostream &OutFile, BinaryHolder &BinHolder, 1045 const DebugMap &DM, LinkOptions Options) { 1046 DwarfLinkerForBinary Linker(OutFile, BinHolder, std::move(Options)); 1047 return Linker.link(DM); 1048 } 1049 1050 } // namespace dsymutil 1051 } // namespace llvm 1052