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