1 //===- tools/dsymutil/DwarfLinkerForBinary.cpp ----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "DwarfLinkerForBinary.h"
10 #include "BinaryHolder.h"
12 #include "MachOUtils.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"
98 #include <system_error>
105 static mc::RegisterMCTargetOptionsFlags MOF
;
109 static Error
copySwiftInterfaces(
110 const std::map
<std::string
, std::string
> &ParseableSwiftInterfaces
,
111 StringRef Architecture
, const LinkOptions
&Options
) {
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();
122 for (auto &I
: ParseableSwiftInterfaces
) {
123 StringRef ModuleName
= I
.first
;
124 StringRef InterfaceFile
= I
.second
;
125 if (!Options
.PrependPath
.empty()) {
127 sys::path::append(InputPath
, Options
.PrependPath
, InterfaceFile
);
128 InterfaceFile
= InputPath
;
130 sys::path::append(Path
, ModuleName
);
131 Path
.append(".swiftinterface");
133 outs() << "copy parseable Swift interface " << InterfaceFile
<< " -> "
134 << Path
.str() << '\n';
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
);
142 return Error::success();
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
,
149 const DWARFDie
*DIE
) const {
151 warn(Warning
, Context
);
153 if (!Options
.Verbose
|| !DIE
)
156 DIDumpOptions DumpOpts
;
157 DumpOpts
.ChildRecurseDepth
= 0;
158 DumpOpts
.Verbose
= Options
.Verbose
;
160 WithColor::note() << " in DIE:\n";
161 DIE
->dump(errs(), 6 /* Indent */, DumpOpts
);
164 bool DwarfLinkerForBinary::createStreamer(const Triple
&TheTriple
,
165 raw_fd_ostream
&OutFile
) {
166 if (Options
.NoOutput
)
169 Streamer
= std::make_unique
<DwarfStreamer
>(
170 Options
.FileType
, OutFile
, Options
.Translator
,
171 [&](const Twine
&Error
, StringRef Context
, const DWARFDie
*) {
172 error(Error
, Context
);
174 [&](const Twine
&Warning
, StringRef Context
, const DWARFDie
*) {
175 warn(Warning
, Context
);
177 return Streamer
->init(TheTriple
, "__DWARF");
180 ErrorOr
<const object::ObjectFile
&>
181 DwarfLinkerForBinary::loadObject(const DebugMapObject
&Obj
,
182 const Triple
&Triple
) {
184 BinHolder
.getObjectEntry(Obj
.getObjectFilename(), Obj
.getTimestamp());
186 auto Err
= ObjectEntry
.takeError();
187 reportWarning(Twine(Obj
.getObjectFilename()) + ": " +
188 toString(std::move(Err
)),
189 Obj
.getObjectFilename());
190 return errorToErrorCode(std::move(Err
));
193 auto Object
= ObjectEntry
->getObject(Triple
);
195 auto Err
= Object
.takeError();
196 reportWarning(Twine(Obj
.getObjectFilename()) + ": " +
197 toString(std::move(Err
)),
198 Obj
.getObjectFilename());
199 return errorToErrorCode(std::move(Err
));
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
212 return Error(std::move(FE
));
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
));
220 Linker
.reportWarning(Message
, DMO
.getObjectFilename());
221 return Error(Error::success());
225 return Error::success();
227 return createFileError(FE
->getFileName(), std::move(NewE
));
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
235 return Error::success();
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
);
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.
255 raw_fd_ostream
OS(Options
.NoOutput
? "-" : Path
.str(), EC
,
256 Options
.RemarksFormat
== remarks::Format::Bitstream
260 return errorCodeToError(EC
);
262 if (Error E
= RL
.serialize(OS
, Options
.RemarksFormat
))
265 return Error::success();
269 DwarfLinkerForBinary::loadObject(const DebugMapObject
&Obj
,
270 const DebugMap
&DebugMap
,
271 remarks::RemarkLinker
&RL
) {
272 auto ErrorOrObj
= loadObject(Obj
, DebugMap
.getTriple());
275 ContextForLinking
.push_back(
276 std::unique_ptr
<DWARFContext
>(DWARFContext::create(*ErrorOrObj
)));
277 AddressMapForLinking
.push_back(
278 std::make_unique
<AddressManager
>(*this, *ErrorOrObj
, Obj
));
280 ObjectsForLinking
.push_back(std::make_unique
<DWARFFile
>(
281 Obj
.getObjectFilename(), ContextForLinking
.back().get(),
282 AddressMapForLinking
.back().get(),
283 Obj
.empty() ? Obj
.getWarnings() : EmptyWarnings
));
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
));
290 return errorToErrorCode(std::move(NewE
));
292 return *ObjectsForLinking
.back();
295 return ErrorOrObj
.getError();
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
) {
306 auto ObjectEntry
= BinHolder
.getObjectEntry(Map
.getBinaryPath());
307 // If ObjectEntry or Object has an error, no binary exists, therefore no
308 // reflection sections exist.
310 // Any errors will be diagnosed later in the main loop, ignore them here.
311 llvm::consumeError(ObjectEntry
.takeError());
316 ObjectEntry
->getObjectAs
<object::MachOObjectFile
>(Map
.getTriple());
318 // Any errors will be diagnosed later in the main loop, ignore them here.
319 llvm::consumeError(Object
.takeError());
323 for (auto &Section
: Object
->sections()) {
324 llvm::Expected
<llvm::StringRef
> NameOrErr
=
325 Object
->getSectionName(Section
.getRawDataRefImpl());
327 llvm::consumeError(NameOrErr
.takeError());
330 NameOrErr
->consume_back("__TEXT");
331 auto ReflectionSectionKind
=
332 Object
->mapReflectionSectionNameToEnumValue(*NameOrErr
);
333 if (Object
->isReflectionSectionStrippable(ReflectionSectionKind
)) {
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()) {
351 llvm::object::ObjectFile::createObjectFile(Obj
->getObjectFilename());
353 llvm::consumeError(OF
.takeError());
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());
361 llvm::consumeError(NameOrErr
.takeError());
364 NameOrErr
->consume_back("__TEXT");
365 auto ReflSectionKind
=
366 MO
->mapReflectionSectionNameToEnumValue(*NameOrErr
);
367 switch (ReflSectionKind
) {
368 case Swift5ReflectionSectionKind::assocty
:
369 AssocTySize
+= Section
.getSize();
371 case Swift5ReflectionSectionKind::fieldmd
:
372 FieldMdSize
+= Section
.getSize();
380 // Initialize the vector with enough space to fit every reflection section
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);
389 return SectionToOffset
;
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
)
399 for (auto It
= Section
.relocation_begin(); It
!= Section
.relocation_end();
401 object::DataRefImpl RelocDataRef
= It
->getRawDataRefImpl();
402 MachO::any_relocation_info MachOReloc
= MO
->getRelocation(RelocDataRef
);
404 if (!object::MachOObjectFile::isMachOPairedReloc(
405 MO
->getAnyRelocationType(MachOReloc
), MO
->getArch())) {
407 "Unimplemented relocation type in strippable reflection section ",
408 Obj
->getObjectFilename());
412 auto CalculateAddressOfSymbolInDwarfSegment
=
413 [&]() -> llvm::Optional
<int64_t> {
414 auto Symbol
= It
->getSymbol();
415 auto SymbolAbsoluteAddress
= Symbol
->getAddress();
416 if (!SymbolAbsoluteAddress
)
418 auto Section
= Symbol
->getSection();
420 llvm::consumeError(Section
.takeError());
424 if ((*Section
)->getObject()->section_end() == *Section
)
427 auto SectionStart
= (*Section
)->getAddress();
428 auto SymbolAddressInSection
= *SymbolAbsoluteAddress
- SectionStart
;
429 auto SectionName
= (*Section
)->getName();
432 auto ReflSectionKind
=
433 MO
->mapReflectionSectionNameToEnumValue(*SectionName
);
435 int64_t SectionStartInLinkedBinary
=
436 SectionToOffsetInDwarf
[ReflSectionKind
];
438 auto Addr
= SectionStartInLinkedBinary
+ SymbolAddressInSection
;
442 // The first symbol should always be in the section we're currently
444 auto FirstSymbolAddress
= CalculateAddressOfSymbolInDwarfSegment();
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();
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;
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();
475 if (!FirstSymbolAddress
|| !SecondSymbolAddress
)
478 auto SectionName
= Section
.getName();
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
);
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
;
501 llvm::object::ObjectFile::createObjectFile(Obj
->getObjectFilename());
503 llvm::consumeError(OF
.takeError());
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>
512 for (auto &Section
: MO
->sections()) {
513 llvm::Expected
<llvm::StringRef
> NameOrErr
=
514 MO
->getSectionName(Section
.getRawDataRefImpl());
516 llvm::consumeError(NameOrErr
.takeError());
519 NameOrErr
->consume_back("__TEXT");
520 auto ReflSectionKind
=
521 MO
->mapReflectionSectionNameToEnumValue(*NameOrErr
);
522 if (MO
->isReflectionSectionStrippable(ReflSectionKind
))
523 SwiftSections
[ReflSectionKind
] = Section
;
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
])
532 auto &Section
= *SwiftSections
[SectionKind
];
533 llvm::Expected
<llvm::StringRef
> SectionContents
= Section
.getContents();
534 if (!SectionContents
)
537 llvm::cast
<llvm::object::MachOObjectFile
>(Section
.getObject());
538 collectRelocationsToApplyToSwiftReflectionSections(
539 Section
, *SectionContents
, MO
, SectionToOffsetInDwarf
, Obj
,
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
544 SectionToOffsetInDwarf
[SectionKind
] += Section
.getSize();
545 Streamer
->emitSwiftReflectionSection(SectionKind
, *SectionContents
,
546 Section
.getAlignment(),
552 bool DwarfLinkerForBinary::link(const DebugMap
&Map
) {
553 if (!createStreamer(Map
.getTriple(), OutFile
))
556 ObjectsForLinking
.clear();
557 ContextForLinking
.clear();
558 AddressMapForLinking
.clear();
560 DebugMap
DebugMap(Map
.getTriple(), Map
.getBinaryPath());
562 DWARFLinker
GeneralLinker(Streamer
.get(), DwarfLinkerClient::Dsymutil
);
564 remarks::RemarkLinker RL
;
565 if (!Options
.RemarksPrependPath
.empty())
566 RL
.setExternalFilePrependPath(Options
.RemarksPrependPath
);
567 GeneralLinker
.setObjectPrefixMap(&Options
.ObjectPrefixMap
);
569 std::function
<StringRef(StringRef
)> TranslationLambda
= [&](StringRef Input
) {
570 assert(Options
.Translator
);
571 return Options
.Translator(Input
);
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
);
590 GeneralLinker
.setErrorHandler(
591 [&](const Twine
&Error
, StringRef Context
, const DWARFDie
*) {
592 error(Error
, Context
);
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
);
600 if (auto ErrorOrObj
= loadObject(Obj
, DebugMap
, RL
)) {
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(")");
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
615 if (!ModuleCacheHintDisplayed
) {
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;
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
628 if (!ArchiveHintDisplayed
) {
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;
641 return ErrorOrObj
.getError();
644 llvm_unreachable("Unhandled DebugMap object");
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
);
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
);
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
) {
669 outs() << "DEBUG MAP OBJECT: " << Obj
->getObjectFilename() << "\n";
671 StringRef File
= Obj
->getObjectFilename();
672 auto ErrorOrMem
= MemoryBuffer::getFile(File
);
674 warn("Could not open '" + File
+ "'\n");
677 sys::fs::file_status Stat
;
678 if (auto Err
= sys::fs::status(File
, Stat
)) {
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<>.
692 << File
<< ": timestamp mismatch between swift interface file ("
693 << sys::TimePoint
<>(ModificationTime
) << ") and debug map ("
694 << sys::TimePoint
<>(Obj
->getTimestamp()) << ")\n";
699 // Copy the module into the .swift_ast section.
700 if (!Options
.NoOutput
)
701 Streamer
->emitSwiftAST((*ErrorOrMem
)->getBuffer());
705 if (auto ErrorOrObj
= loadObject(*Obj
, Map
, RL
))
706 GeneralLinker
.addObjectFile(*ErrorOrObj
);
708 ObjectsForLinking
.push_back(std::make_unique
<DWARFFile
>(
709 Obj
->getObjectFilename(), nullptr, nullptr,
710 Obj
->empty() ? Obj
->getWarnings() : EmptyWarnings
));
711 GeneralLinker
.addObjectFile(*ObjectsForLinking
.back());
715 // link debug info for loaded object files.
716 if (Error E
= GeneralLinker
.link())
717 return error(toString(std::move(E
)));
719 StringRef ArchName
= Map
.getTriple().getArchName();
720 if (Error E
= emitRemarks(Options
, Map
.getBinaryPath(), ArchName
, RL
))
721 return error(toString(std::move(E
)));
723 if (Options
.NoOutput
)
726 if (Options
.ResourceDir
&& !ParseableSwiftInterfaces
.empty()) {
727 StringRef ArchName
= Triple::getArchTypeName(Map
.getTriple().getArch());
729 copySwiftInterfaces(ParseableSwiftInterfaces
, ArchName
, Options
))
730 return error(toString(std::move(E
)));
733 if (Map
.getTriple().isOSDarwin() && !Map
.getBinaryPath().empty() &&
734 Options
.FileType
== OutputFileType::Object
)
735 return MachOUtils::generateDsymCompanion(
736 Options
.VFS
, Map
, Options
.Translator
,
737 *Streamer
->getAsmPrinter().OutStreamer
, OutFile
, RelocationsToApply
);
743 /// Iterate over the relocations of the given \p Section and
744 /// store the ones that correspond to debug map entries into the
745 /// ValidRelocs array.
746 void DwarfLinkerForBinary::AddressManager::findValidRelocsMachO(
747 const object::SectionRef
&Section
, const object::MachOObjectFile
&Obj
,
748 const DebugMapObject
&DMO
, std::vector
<ValidReloc
> &ValidRelocs
) {
749 Expected
<StringRef
> ContentsOrErr
= Section
.getContents();
750 if (!ContentsOrErr
) {
751 consumeError(ContentsOrErr
.takeError());
752 Linker
.reportWarning("error reading section", DMO
.getObjectFilename());
755 DataExtractor
Data(*ContentsOrErr
, Obj
.isLittleEndian(), 0);
756 bool SkipNext
= false;
758 for (const object::RelocationRef
&Reloc
: Section
.relocations()) {
764 object::DataRefImpl RelocDataRef
= Reloc
.getRawDataRefImpl();
765 MachO::any_relocation_info MachOReloc
= Obj
.getRelocation(RelocDataRef
);
767 if (object::MachOObjectFile::isMachOPairedReloc(Obj
.getAnyRelocationType(MachOReloc
),
770 Linker
.reportWarning("unsupported relocation in " + *Section
.getName() +
772 DMO
.getObjectFilename());
776 unsigned RelocSize
= 1 << Obj
.getAnyRelocationLength(MachOReloc
);
777 uint64_t Offset64
= Reloc
.getOffset();
778 if ((RelocSize
!= 4 && RelocSize
!= 8)) {
779 Linker
.reportWarning("unsupported relocation in " + *Section
.getName() +
781 DMO
.getObjectFilename());
784 uint64_t OffsetCopy
= Offset64
;
785 // Mach-o uses REL relocations, the addend is at the relocation offset.
786 uint64_t Addend
= Data
.getUnsigned(&OffsetCopy
, RelocSize
);
790 if (Obj
.isRelocationScattered(MachOReloc
)) {
791 // The address of the base symbol for scattered relocations is
792 // stored in the reloc itself. The actual addend will store the
793 // base address plus the offset.
794 SymAddress
= Obj
.getScatteredRelocationValue(MachOReloc
);
795 SymOffset
= int64_t(Addend
) - SymAddress
;
801 auto Sym
= Reloc
.getSymbol();
802 if (Sym
!= Obj
.symbol_end()) {
803 Expected
<StringRef
> SymbolName
= Sym
->getName();
805 consumeError(SymbolName
.takeError());
806 Linker
.reportWarning("error getting relocation symbol name.",
807 DMO
.getObjectFilename());
810 if (const auto *Mapping
= DMO
.lookupSymbol(*SymbolName
))
811 ValidRelocs
.emplace_back(Offset64
, RelocSize
, Addend
, Mapping
);
812 } else if (const auto *Mapping
= DMO
.lookupObjectAddress(SymAddress
)) {
813 // Do not store the addend. The addend was the address of the symbol in
814 // the object file, the address in the binary that is stored in the debug
815 // map doesn't need to be offset.
816 ValidRelocs
.emplace_back(Offset64
, RelocSize
, SymOffset
, Mapping
);
821 /// Dispatch the valid relocation finding logic to the
822 /// appropriate handler depending on the object file format.
823 bool DwarfLinkerForBinary::AddressManager::findValidRelocs(
824 const object::SectionRef
&Section
, const object::ObjectFile
&Obj
,
825 const DebugMapObject
&DMO
, std::vector
<ValidReloc
> &Relocs
) {
826 // Dispatch to the right handler depending on the file type.
827 if (auto *MachOObj
= dyn_cast
<object::MachOObjectFile
>(&Obj
))
828 findValidRelocsMachO(Section
, *MachOObj
, DMO
, Relocs
);
830 Linker
.reportWarning(Twine("unsupported object file type: ") +
832 DMO
.getObjectFilename());
836 // Sort the relocations by offset. We will walk the DIEs linearly in
837 // the file, this allows us to just keep an index in the relocation
838 // array that we advance during our walk, rather than resorting to
839 // some associative container. See DwarfLinkerForBinary::NextValidReloc.
844 /// Look for relocations in the debug_info and debug_addr section that match
845 /// entries in the debug map. These relocations will drive the Dwarf link by
846 /// indicating which DIEs refer to symbols present in the linked binary.
847 /// \returns whether there are any valid relocations in the debug info.
848 bool DwarfLinkerForBinary::AddressManager::findValidRelocsInDebugSections(
849 const object::ObjectFile
&Obj
, const DebugMapObject
&DMO
) {
850 // Find the debug_info section.
851 bool FoundValidRelocs
= false;
852 for (const object::SectionRef
&Section
: Obj
.sections()) {
853 StringRef SectionName
;
854 if (Expected
<StringRef
> NameOrErr
= Section
.getName())
855 SectionName
= *NameOrErr
;
857 consumeError(NameOrErr
.takeError());
859 SectionName
= SectionName
.substr(SectionName
.find_first_not_of("._"));
860 if (SectionName
== "debug_info")
862 findValidRelocs(Section
, Obj
, DMO
, ValidDebugInfoRelocs
);
863 if (SectionName
== "debug_addr")
865 findValidRelocs(Section
, Obj
, DMO
, ValidDebugAddrRelocs
);
867 return FoundValidRelocs
;
870 std::vector
<DwarfLinkerForBinary::AddressManager::ValidReloc
>
871 DwarfLinkerForBinary::AddressManager::getRelocations(
872 const std::vector
<ValidReloc
> &Relocs
, uint64_t StartPos
, uint64_t EndPos
) {
873 std::vector
<DwarfLinkerForBinary::AddressManager::ValidReloc
> Res
;
875 auto CurReloc
= partition_point(Relocs
, [StartPos
](const ValidReloc
&Reloc
) {
876 return Reloc
.Offset
< StartPos
;
879 while (CurReloc
!= Relocs
.end() && CurReloc
->Offset
>= StartPos
&&
880 CurReloc
->Offset
< EndPos
) {
881 Res
.push_back(*CurReloc
);
888 void DwarfLinkerForBinary::AddressManager::printReloc(const ValidReloc
&Reloc
) {
889 const auto &Mapping
= Reloc
.Mapping
->getValue();
890 const uint64_t ObjectAddress
= Mapping
.ObjectAddress
891 ? uint64_t(*Mapping
.ObjectAddress
)
892 : std::numeric_limits
<uint64_t>::max();
894 outs() << "Found valid debug map entry: " << Reloc
.Mapping
->getKey() << "\t"
895 << format("0x%016" PRIx64
" => 0x%016" PRIx64
"\n", ObjectAddress
,
896 uint64_t(Mapping
.BinaryAddress
));
899 void DwarfLinkerForBinary::AddressManager::fillDieInfo(
900 const ValidReloc
&Reloc
, CompileUnit::DIEInfo
&Info
) {
901 Info
.AddrAdjust
= relocate(Reloc
);
902 if (Reloc
.Mapping
->getValue().ObjectAddress
)
903 Info
.AddrAdjust
-= uint64_t(*Reloc
.Mapping
->getValue().ObjectAddress
);
904 Info
.InDebugMap
= true;
907 bool DwarfLinkerForBinary::AddressManager::hasValidRelocationAt(
908 const std::vector
<ValidReloc
> &AllRelocs
, uint64_t StartOffset
,
909 uint64_t EndOffset
, CompileUnit::DIEInfo
&Info
) {
910 std::vector
<ValidReloc
> Relocs
=
911 getRelocations(AllRelocs
, StartOffset
, EndOffset
);
913 if (Relocs
.size() == 0)
916 if (Linker
.Options
.Verbose
)
917 printReloc(Relocs
[0]);
918 fillDieInfo(Relocs
[0], Info
);
923 /// Get the starting and ending (exclusive) offset for the
924 /// attribute with index \p Idx descibed by \p Abbrev. \p Offset is
925 /// supposed to point to the position of the first attribute described
927 /// \return [StartOffset, EndOffset) as a pair.
928 static std::pair
<uint64_t, uint64_t>
929 getAttributeOffsets(const DWARFAbbreviationDeclaration
*Abbrev
, unsigned Idx
,
930 uint64_t Offset
, const DWARFUnit
&Unit
) {
931 DataExtractor Data
= Unit
.getDebugInfoExtractor();
933 for (unsigned I
= 0; I
< Idx
; ++I
)
934 DWARFFormValue::skipValue(Abbrev
->getFormByIndex(I
), Data
, &Offset
,
935 Unit
.getFormParams());
937 uint64_t End
= Offset
;
938 DWARFFormValue::skipValue(Abbrev
->getFormByIndex(Idx
), Data
, &End
,
939 Unit
.getFormParams());
941 return std::make_pair(Offset
, End
);
944 bool DwarfLinkerForBinary::AddressManager::isLiveVariable(
945 const DWARFDie
&DIE
, CompileUnit::DIEInfo
&MyInfo
) {
946 const auto *Abbrev
= DIE
.getAbbreviationDeclarationPtr();
948 Optional
<uint32_t> LocationIdx
=
949 Abbrev
->findAttributeIndex(dwarf::DW_AT_location
);
953 uint64_t Offset
= DIE
.getOffset() + getULEB128Size(Abbrev
->getCode());
954 uint64_t LocationOffset
, LocationEndOffset
;
955 std::tie(LocationOffset
, LocationEndOffset
) =
956 getAttributeOffsets(Abbrev
, *LocationIdx
, Offset
, *DIE
.getDwarfUnit());
958 // FIXME: Support relocations debug_addr.
959 return hasValidRelocationAt(ValidDebugInfoRelocs
, LocationOffset
,
960 LocationEndOffset
, MyInfo
);
963 bool DwarfLinkerForBinary::AddressManager::isLiveSubprogram(
964 const DWARFDie
&DIE
, CompileUnit::DIEInfo
&MyInfo
) {
965 const auto *Abbrev
= DIE
.getAbbreviationDeclarationPtr();
967 Optional
<uint32_t> LowPcIdx
= Abbrev
->findAttributeIndex(dwarf::DW_AT_low_pc
);
971 dwarf::Form Form
= Abbrev
->getFormByIndex(*LowPcIdx
);
973 if (Form
== dwarf::DW_FORM_addr
) {
974 uint64_t Offset
= DIE
.getOffset() + getULEB128Size(Abbrev
->getCode());
975 uint64_t LowPcOffset
, LowPcEndOffset
;
976 std::tie(LowPcOffset
, LowPcEndOffset
) =
977 getAttributeOffsets(Abbrev
, *LowPcIdx
, Offset
, *DIE
.getDwarfUnit());
978 return hasValidRelocationAt(ValidDebugInfoRelocs
, LowPcOffset
,
979 LowPcEndOffset
, MyInfo
);
982 if (Form
== dwarf::DW_FORM_addrx
) {
983 Optional
<DWARFFormValue
> AddrValue
= DIE
.find(dwarf::DW_AT_low_pc
);
984 if (Optional
<uint64_t> AddrOffsetSectionBase
=
985 DIE
.getDwarfUnit()->getAddrOffsetSectionBase()) {
986 uint64_t StartOffset
= *AddrOffsetSectionBase
+ AddrValue
->getRawUValue();
988 StartOffset
+ DIE
.getDwarfUnit()->getAddressByteSize();
989 return hasValidRelocationAt(ValidDebugAddrRelocs
, StartOffset
, EndOffset
,
992 Linker
.reportWarning("no base offset for address table", SrcFileName
);
999 DwarfLinkerForBinary::AddressManager::relocate(const ValidReloc
&Reloc
) const {
1000 return Reloc
.Mapping
->getValue().BinaryAddress
+ Reloc
.Addend
;
1003 /// Apply the valid relocations found by findValidRelocs() to
1004 /// the buffer \p Data, taking into account that Data is at \p BaseOffset
1005 /// in the debug_info section.
1007 /// Like for findValidRelocs(), this function must be called with
1008 /// monotonic \p BaseOffset values.
1010 /// \returns whether any reloc has been applied.
1011 bool DwarfLinkerForBinary::AddressManager::applyValidRelocs(
1012 MutableArrayRef
<char> Data
, uint64_t BaseOffset
, bool IsLittleEndian
) {
1013 std::vector
<ValidReloc
> Relocs
= getRelocations(
1014 ValidDebugInfoRelocs
, BaseOffset
, BaseOffset
+ Data
.size());
1016 for (const ValidReloc
&CurReloc
: Relocs
) {
1017 assert(CurReloc
.Offset
- BaseOffset
< Data
.size());
1018 assert(CurReloc
.Offset
- BaseOffset
+ CurReloc
.Size
<= Data
.size());
1020 uint64_t Value
= relocate(CurReloc
);
1021 for (unsigned I
= 0; I
!= CurReloc
.Size
; ++I
) {
1022 unsigned Index
= IsLittleEndian
? I
: (CurReloc
.Size
- I
- 1);
1023 Buf
[I
] = uint8_t(Value
>> (Index
* 8));
1025 assert(CurReloc
.Size
<= sizeof(Buf
));
1026 memcpy(&Data
[CurReloc
.Offset
- BaseOffset
], Buf
, CurReloc
.Size
);
1029 return Relocs
.size() > 0;
1032 llvm::Expected
<uint64_t>
1033 DwarfLinkerForBinary::AddressManager::relocateIndexedAddr(uint64_t StartOffset
,
1034 uint64_t EndOffset
) {
1035 std::vector
<ValidReloc
> Relocs
=
1036 getRelocations(ValidDebugAddrRelocs
, StartOffset
, EndOffset
);
1037 if (Relocs
.size() == 0)
1038 return createStringError(
1039 std::make_error_code(std::errc::invalid_argument
),
1040 "no relocation for offset %llu in debug_addr section", StartOffset
);
1042 return relocate(Relocs
[0]);
1045 bool linkDwarf(raw_fd_ostream
&OutFile
, BinaryHolder
&BinHolder
,
1046 const DebugMap
&DM
, LinkOptions Options
) {
1047 DwarfLinkerForBinary
Linker(OutFile
, BinHolder
, std::move(Options
));
1048 return Linker
.link(DM
);
1051 } // namespace dsymutil