Revert "[dsymutil] Add support for mergeable libraries"

This reverts commit 122c89b271. Change does not build, with errors such as:

In file included from ../llvm-project/llvm/tools/dsymutil/DebugMap.h:24,
                 from ../llvm-project/llvm/tools/dsymutil/DwarfLinkerForBinary.h:13,
                 from ../llvm-project/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp:9:
../llvm-project/llvm/tools/dsymutil/RelocationMap.h:60:17: error: declaration of ‘llvm::dsymutil::SymbolMapping llvm::dsymutil::ValidReloc::SymbolMapping’ changes meaning of ‘SymbolMapping’ [-fpermissive]
   60 |   SymbolMapping SymbolMapping;
      |                 ^~~~~~~~~~~~~
../llvm-project/llvm/tools/dsymutil/RelocationMap.h:36:8: note: ‘SymbolMapping’ declared here as ‘struct llvm::dsymutil::SymbolMapping’
   36 | struct SymbolMapping {
      |        ^~~~~~~~~~~~~
In file included from ../llvm-project/llvm/tools/dsymutil/DwarfLinkerForBinary.h:13,
                 from ../llvm-project/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp:9:
../llvm-project/llvm/tools/dsymutil/DebugMap.h:198:32: error: declaration of ‘std::optional<llvm::dsymutil::RelocationMap> llvm::dsymutil::DebugMapObject::RelocationMap’ changes meaning of ‘RelocationMap’ [-fpermissive]
  198 |   std::optional<RelocationMap> RelocationMap;
      |                                ^~~~~~~~~~~~~
In file included from ../llvm-project/llvm/tools/dsymutil/DebugMap.h:24,
                 from ../llvm-project/llvm/tools/dsymutil/DwarfLinkerForBinary.h:13,
                 from ../llvm-project/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp:9:
../llvm-project/llvm/tools/dsymutil/RelocationMap.h:76:7: note: ‘RelocationMap’ declared here as ‘class llvm::dsymutil::RelocationMap’
   76 | class RelocationMap {
      |       ^~~~~~~~~~~~~
This commit is contained in:
Philip Reames 2023-10-24 11:43:23 -07:00 committed by Philip Reames
parent 3a72bcbf33
commit 717946f9eb
34 changed files with 198 additions and 1217 deletions

View File

@ -32,26 +32,11 @@ OPTIONS
architectures will be linked by default and any architectures that can't be
properly linked will cause :program:`dsymutil` to return an error.
.. option:: --build-variant-suffix <suffix=buildvariant>
Specify the build variant suffix used to build the executabe file.
There can be multiple variants for the binary of a product, each built
slightly differently. The most common build variants are 'debug' and
'profile'. Setting the DYLD_IMAGE_SUFFIX environment variable will
cause dyld to load the specified variant at runtime.
.. option:: --dump-debug-map
Dump the *executable*'s debug-map (the list of the object files containing the
debug information) in YAML format and exit. No DWARF link will take place.
.. option:: -D <path>
Specify a directory that contain dSYM files to search for.
This is used for mergeable libraries, so dsymutil knows where to look
for dSYM files with debug information about symbols present in those
libraries.
.. option:: --fat64
Use a 64-bit header when emitting universal binaries.

View File

@ -629,7 +629,6 @@ HANDLE_DW_AT(0x3fec, APPLE_objc_complete_type, 0, APPLE)
HANDLE_DW_AT(0x3fed, APPLE_property, 0, APPLE)
HANDLE_DW_AT(0x3fee, APPLE_objc_direct, 0, APPLE)
HANDLE_DW_AT(0x3fef, APPLE_sdk, 0, APPLE)
HANDLE_DW_AT(0x3ff0, APPLE_origin, 0, APPLE)
// Attribute form encodings.
HANDLE_DW_FORM(0x01, addr, 2, DWARF)

View File

@ -373,7 +373,6 @@ enum StabType {
N_SSYM = 0x60u,
N_SO = 0x64u,
N_OSO = 0x66u,
N_LIB = 0x68u,
N_LSYM = 0x80u,
N_BINCL = 0x82u,
N_SOL = 0x84u,

View File

@ -62,9 +62,6 @@ public:
virtual std::optional<int64_t>
getSubprogramRelocAdjustment(const DWARFDie &DIE) = 0;
/// Returns the file name associated to the AddessesMap
virtual std::optional<StringRef> getLibraryInstallName() = 0;
/// Apply the valid relocations to the buffer \p Data, taking into
/// account that Data is at \p BaseOffset in the .debug_info section.
///
@ -72,23 +69,6 @@ public:
virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
bool IsLittleEndian) = 0;
/// Check if the linker needs to gather and save relocation info.
virtual bool needToSaveValidRelocs() = 0;
/// Update and save original relocations located in between StartOffset and
/// EndOffset. LinkedOffset is the value which should be added to the original
/// relocation offset to get new relocation offset in linked binary.
virtual void updateAndSaveValidRelocs(bool IsDWARF5,
uint64_t OriginalUnitOffset,
int64_t LinkedOffset,
uint64_t StartOffset,
uint64_t EndOffset) = 0;
/// Update the valid relocations that used OriginalUnitOffset as the compile
/// unit offset, and update their values to reflect OutputUnitOffset.
virtual void updateRelocationsWithUnitOffset(uint64_t OriginalUnitOffset,
uint64_t OutputUnitOffset) = 0;
/// Erases all data.
virtual void clear() = 0;
};
@ -772,9 +752,6 @@ private:
/// Is there a DW_AT_str_offsets_base in the CU?
bool AttrStrOffsetBaseSeen = false;
/// Is there a DW_AT_APPLE_origin in the CU?
bool HasAppleOrigin = false;
AttributesInfo() = default;
};

View File

@ -55,9 +55,6 @@ public:
virtual std::optional<int64_t>
getSubprogramRelocAdjustment(const DWARFDie &DIE) = 0;
// Returns the library install name associated to the AddessesMap.
virtual std::optional<StringRef> getLibraryInstallName() = 0;
/// Apply the valid relocations to the buffer \p Data, taking into
/// account that Data is at \p BaseOffset in the .debug_info section.
///
@ -65,21 +62,6 @@ public:
virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
bool IsLittleEndian) = 0;
/// Check if the linker needs to gather and save relocation info.
virtual bool needToSaveValidRelocs() = 0;
/// Update and save relocation values to be serialized
virtual void updateAndSaveValidRelocs(bool IsDWARF5,
uint64_t OriginalUnitOffset,
int64_t LinkedOffset,
uint64_t StartOffset,
uint64_t EndOffset) = 0;
/// Update the valid relocations that used OriginalUnitOffset as the compile
/// unit offset, and update their values to reflect OutputUnitOffset.
virtual void updateRelocationsWithUnitOffset(uint64_t OriginalUnitOffset,
uint64_t OutputUnitOffset) = 0;
/// Erases all data.
virtual void clear() = 0;

View File

@ -418,6 +418,9 @@ public:
/// Get the architecture (first) component of the triple.
StringRef getArchName() const;
/// Get the architecture name based on Kind and SubArch.
StringRef getArchName(ArchType Kind, SubArchType SubArch = NoSubArch) const;
/// Get the vendor (second) component of the triple.
StringRef getVendorName() const;
@ -1115,9 +1118,6 @@ public:
/// Get the canonical name for the \p Kind architecture.
static StringRef getArchTypeName(ArchType Kind);
/// Get the architecture name based on \p Kind and \p SubArch.
static StringRef getArchName(ArchType Kind, SubArchType SubArch = NoSubArch);
/// Get the "prefix" canonical name for the \p Kind architecture. This is the
/// prefix used by the architecture specific builtins, and is suitable for
/// passing to \see Intrinsic::getIntrinsicForClangBuiltin().

View File

@ -1026,15 +1026,6 @@ unsigned DWARFLinker::DIECloner::cloneStringAttribute(DIE &Die,
StringEntry = DebugLineStrPool.getEntry(*String);
} else {
StringEntry = DebugStrPool.getEntry(*String);
if (AttrSpec.Attr == dwarf::DW_AT_APPLE_origin) {
Info.HasAppleOrigin = true;
if (std::optional<StringRef> FileName =
ObjFile.Addresses->getLibraryInstallName()) {
StringEntry = DebugStrPool.getEntry(*FileName);
}
}
// Update attributes info.
if (AttrSpec.Attr == dwarf::DW_AT_name)
Info.Name = StringEntry;
@ -1646,12 +1637,6 @@ shouldSkipAttribute(bool Update,
}
}
struct AttributeLinkedOffsetFixup {
int64_t LinkedOffsetFixupVal;
uint64_t InputAttrStartOffset;
uint64_t InputAttrEndOffset;
};
DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
const DWARFFile &File, CompileUnit &Unit,
int64_t PCOffset, uint32_t OutOffset,
@ -1735,9 +1720,6 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
Flags |= TF_SkipPC;
}
std::optional<StringRef> LibraryInstallName =
ObjFile.Addresses->getLibraryInstallName();
SmallVector<AttributeLinkedOffsetFixup> AttributesFixups;
for (const auto &AttrSpec : Abbrev->attributes()) {
if (shouldSkipAttribute(Update, AttrSpec, Flags & TF_SkipPC)) {
DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
@ -1745,41 +1727,17 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
continue;
}
AttributeLinkedOffsetFixup CurAttrFixup;
CurAttrFixup.InputAttrStartOffset = InputDIE.getOffset() + Offset;
CurAttrFixup.LinkedOffsetFixupVal =
Unit.getStartOffset() + OutOffset - CurAttrFixup.InputAttrStartOffset;
DWARFFormValue Val = AttrSpec.getFormValue();
uint64_t AttrSize = Offset;
Val.extractValue(Data, &Offset, U.getFormParams(), &U);
CurAttrFixup.InputAttrEndOffset = InputDIE.getOffset() + Offset;
AttrSize = Offset - AttrSize;
uint64_t FinalAttrSize =
cloneAttribute(*Die, InputDIE, File, Unit, Val, AttrSpec, AttrSize,
AttrInfo, IsLittleEndian);
if (FinalAttrSize != 0 && ObjFile.Addresses->needToSaveValidRelocs())
AttributesFixups.push_back(CurAttrFixup);
OutOffset += FinalAttrSize;
}
uint16_t Tag = InputDIE.getTag();
// Add the DW_AT_APPLE_origin attribute to Compile Unit die if we have
// an install name and the DWARF doesn't have the attribute yet.
const bool NeedsAppleOrigin = (Tag == dwarf::DW_TAG_compile_unit) &&
LibraryInstallName.has_value() &&
!AttrInfo.HasAppleOrigin;
if (NeedsAppleOrigin) {
auto StringEntry = DebugStrPool.getEntry(LibraryInstallName.value());
Die->addValue(DIEAlloc, dwarf::Attribute(dwarf::DW_AT_APPLE_origin),
dwarf::DW_FORM_strp, DIEInteger(StringEntry.getOffset()));
AttrInfo.Name = StringEntry;
OutOffset += 4;
OutOffset += cloneAttribute(*Die, InputDIE, File, Unit, Val, AttrSpec,
AttrSize, AttrInfo, IsLittleEndian);
}
// Look for accelerator entries.
uint16_t Tag = InputDIE.getTag();
// FIXME: This is slightly wrong. An inline_subroutine without a
// low_pc, but with AT_ranges might be interesting to get into the
// accelerator tables too. For now stick with dsymutil's behavior.
@ -1848,19 +1806,8 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
Linker.assignAbbrev(NewAbbrev);
Die->setAbbrevNumber(NewAbbrev.getNumber());
uint64_t AbbrevNumberSize = getULEB128Size(Die->getAbbrevNumber());
// Add the size of the abbreviation number to the output offset.
OutOffset += AbbrevNumberSize;
// Update fixups with the size of the abbreviation number
for (AttributeLinkedOffsetFixup &F : AttributesFixups)
F.LinkedOffsetFixupVal += AbbrevNumberSize;
for (AttributeLinkedOffsetFixup &F : AttributesFixups)
ObjFile.Addresses->updateAndSaveValidRelocs(
Unit.getOrigUnit().getVersion() >= 5, Unit.getOrigUnit().getOffset(),
F.LinkedOffsetFixupVal, F.InputAttrStartOffset, F.InputAttrEndOffset);
OutOffset += getULEB128Size(Die->getAbbrevNumber());
if (!HasChildren) {
// Update our size.

View File

@ -90,36 +90,6 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
llvm_unreachable("Invalid ArchType!");
}
StringRef Triple::getArchName(ArchType Kind, SubArchType SubArch) {
switch (Kind) {
case Triple::mips:
if (SubArch == MipsSubArch_r6)
return "mipsisa32r6";
break;
case Triple::mipsel:
if (SubArch == MipsSubArch_r6)
return "mipsisa32r6el";
break;
case Triple::mips64:
if (SubArch == MipsSubArch_r6)
return "mipsisa64r6";
break;
case Triple::mips64el:
if (SubArch == MipsSubArch_r6)
return "mipsisa64r6el";
break;
case Triple::aarch64:
if (SubArch == AArch64SubArch_arm64ec)
return "arm64ec";
if (SubArch == AArch64SubArch_arm64e)
return "arm64e";
break;
default:
break;
}
return getArchTypeName(Kind);
}
StringRef Triple::getArchTypePrefix(ArchType Kind) {
switch (Kind) {
default:
@ -1173,6 +1143,34 @@ StringRef Triple::getArchName() const {
return StringRef(Data).split('-').first; // Isolate first component
}
StringRef Triple::getArchName(ArchType Kind, SubArchType SubArch) const {
switch (Kind) {
case Triple::mips:
if (SubArch == MipsSubArch_r6)
return "mipsisa32r6";
break;
case Triple::mipsel:
if (SubArch == MipsSubArch_r6)
return "mipsisa32r6el";
break;
case Triple::mips64:
if (SubArch == MipsSubArch_r6)
return "mipsisa64r6";
break;
case Triple::mips64el:
if (SubArch == MipsSubArch_r6)
return "mipsisa64r6el";
break;
case Triple::aarch64:
if (SubArch == AArch64SubArch_arm64ec)
return "arm64ec";
break;
default:
break;
}
return getArchTypeName(Kind);
}
StringRef Triple::getVendorName() const {
StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
return Tmp.split('-').first; // Isolate second component

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.bar-relink-variant.dylib</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -1,8 +0,0 @@
---
triple: 'arm64-apple-darwin'
binary-path: bar-relink-variant.dylib
relocations:
- { offset: 0x26, size: 0x8, addend: 0x0, symName: _bar, symObjAddr: 0x0, symBinAddr: 0x3FA0, symSize: 0x8 }
- { offset: 0x3F, size: 0x8, addend: 0x0, symName: _baz, symObjAddr: 0x8, symBinAddr: 0x4000, symSize: 0x0 }
- { offset: 0x4F, size: 0x8, addend: 0x0, symName: _bar, symObjAddr: 0x0, symBinAddr: 0x3FA0, symSize: 0x8 }
...

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.bar-relink.dylib</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -1,8 +0,0 @@
---
triple: 'arm64-apple-darwin'
binary-path: bar-relink.dylib
relocations:
- { offset: 0x26, size: 0x8, addend: 0x0, symName: _bar, symObjAddr: 0x0, symBinAddr: 0x3FA0, symSize: 0x8 }
- { offset: 0x3F, size: 0x8, addend: 0x0, symName: _baz, symObjAddr: 0x8, symBinAddr: 0x4000, symSize: 0x0 }
- { offset: 0x4F, size: 0x8, addend: 0x0, symName: _bar, symObjAddr: 0x0, symBinAddr: 0x3FA0, symSize: 0x8 }
...

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.foo-relink-variant.dylib</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -1,9 +0,0 @@
---
triple: 'arm64-apple-darwin'
binary-path: foo-relink-variant.dylib
relocations:
- { offset: 0x26, size: 0x8, addend: 0x0, symName: _foo, symObjAddr: 0x0, symBinAddr: 0x3F64, symSize: 0x20 }
- { offset: 0x33, size: 0x8, addend: 0x0, symName: _foo, symObjAddr: 0x0, symBinAddr: 0x3F64, symSize: 0x20 }
- { offset: 0x88, size: 0x8, addend: 0x0, symName: _altfoo, symObjAddr: 0x0, symBinAddr: 0x3F84, symSize: 0x24 }
- { offset: 0x95, size: 0x8, addend: 0x0, symName: _altfoo, symObjAddr: 0x0, symBinAddr: 0x3F84, symSize: 0x24 }
...

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.foo-relink.dylib</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -1,10 +0,0 @@
---
triple: 'arm64-apple-darwin'
binary-path: foo-relink.dylib
relocations:
- { offset: 0x26, size: 0x8, addend: 0x0, symName: _foo, symObjAddr: 0x0, symBinAddr: 0x3F54, symSize: 0x20 }
- { offset: 0x33, size: 0x8, addend: 0x0, symName: _foo, symObjAddr: 0x0, symBinAddr: 0x3F54, symSize: 0x20 }
- { offset: 0x5B, size: 0x8, addend: 0x0, symName: _foo_unused, symObjAddr: 0x20, symBinAddr: 0x3F74, symSize: 0x8 }
- { offset: 0xA1, size: 0x8, addend: 0x0, symName: _altfoo, symObjAddr: 0x0, symBinAddr: 0x3F7C, symSize: 0x24 }
- { offset: 0xAE, size: 0x8, addend: 0x0, symName: _altfoo, symObjAddr: 0x0, symBinAddr: 0x3F7C, symSize: 0x24 }
...

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.proxy-relink.dylib</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -1,14 +0,0 @@
---
triple: 'arm64-apple-darwin'
binary-path: proxy-relink.dylib
relocations:
- { offset: 0x26, size: 0x8, addend: 0x0, symName: _display, symObjAddr: 0x0, symBinAddr: 0x3F1C, symSize: 0x1C }
- { offset: 0x41, size: 0x8, addend: 0x0, symName: _display, symObjAddr: 0x0, symBinAddr: 0x3F1C, symSize: 0x1C }
- { offset: 0x7C, size: 0x8, addend: 0x0, symName: _bar, symObjAddr: 0x3FA0, symBinAddr: 0x3F38, symSize: 0x8 }
- { offset: 0x99, size: 0x8, addend: 0x0, symName: _baz, symObjAddr: 0x4000, symBinAddr: 0x8000, symSize: 0x0 }
- { offset: 0xA9, size: 0x8, addend: 0x0, symName: _bar, symObjAddr: 0x3FA0, symBinAddr: 0x3F38, symSize: 0x8 }
- { offset: 0xE8, size: 0x8, addend: 0x0, symName: _foo, symObjAddr: 0x3F60, symBinAddr: 0x3F40, symSize: 0x24 }
- { offset: 0xF9, size: 0x8, addend: 0x0, symName: _foo, symObjAddr: 0x3F60, symBinAddr: 0x3F40, symSize: 0x24 }
- { offset: 0x14E, size: 0x8, addend: 0x0, symName: _altfoo, symObjAddr: 0x3F84, symBinAddr: 0x3F64, symSize: 0x24 }
- { offset: 0x15F, size: 0x8, addend: 0x0, symName: _altfoo, symObjAddr: 0x3F84, symBinAddr: 0x3F64, symSize: 0x24 }
...

View File

@ -2,9 +2,6 @@ RUN: dsymutil -no-output -verbose -oso-prepend-path=%p %p/Inputs/basic.macho.x86
RUN: dsymutil -no-output -verbose -oso-prepend-path=%p %p/Inputs/basic-lto.macho.x86_64 | FileCheck %s --check-prefix=CHECK-LTO
RUN: dsymutil -no-output -verbose -oso-prepend-path=%p %p/Inputs/basic-archive.macho.x86_64 | FileCheck %s --check-prefix=CHECK-ARCHIVE
RUN: dsymutil -no-output -verbose -oso-prepend-path=%p %p/Inputs/basic.macho.x86_64 %p/Inputs/basic-lto.macho.x86_64 %p/Inputs/basic-archive.macho.x86_64 | FileCheck %s --check-prefixes=CHECK,CHECK-LTO,CHECK-ARCHIVE
RUN: dsymutil -no-output -verbose -oso-prepend-path=%p -D %p/Inputs %p/Inputs/basic-relink.macho.arm64.dylib | FileCheck %s --check-prefix=CHECK-RELINK
RUN: dsymutil -no-output -verbose -oso-prepend-path=%p -D %p/Inputs %p/Inputs/two-level-relink.macho.arm64.dylib | FileCheck %s --check-prefix=CHECK-RELINK-TWO
RUN: dsymutil -no-output -verbose -oso-prepend-path=%p -build-variant-suffix=_debug -D WrongPath -D %p/Inputs %p/Inputs/variant-relink.macho.arm64.dylib | FileCheck %s --check-prefix=CHECK-RELINK-VARIANT
This test check the basic Dwarf linking process through the debug dumps.
@ -178,122 +175,3 @@ CHECK-ARCHIVE: Found valid debug map entry: _inc 0x0000000000000070 => 0x0000000
CHECK-ARCHIVE-NEXT: Keeping subprogram DIE:
CHECK-ARCHIVE-NEXT: DW_TAG_subprogram
CHECK-ARCHIVE-NEXT: DW_AT_name {{.*}}"inc")
================================= Simple relink ================================
CHECK-RELINK: DEBUG MAP OBJECT: {{.*}}basic-relink.macho.arm64.o
CHECK-RELINK: Input compilation unit:
CHECK-RELINK-NEXT: TAG_compile_unit
CHECK-RELINK-NOT: TAG
CHECK-RELINK: AT_name {{.*}}basic-relink.macho.arm64.c
CHECK-RELINK: DEBUG MAP OBJECT: {{.*}}foo-relink.dylib
CHECK-RELINK: Input compilation unit:
CHECK-RELINK-NEXT: TAG_compile_unit
CHECK-RELINK-NOT: TAG
CHECK-RELINK: AT_name {{.*}}foo-relink.c
CHECK-RELINK: Input compilation unit:
CHECK-RELINK-NEXT: TAG_compile_unit
CHECK-RELINK-NOT: TAG
CHECK-RELINK: AT_name {{.*}}altfoo-relink.c
CHECK-RELINK: DEBUG MAP OBJECT: {{.*}}bar-relink.dylib
CHECK-RELINK: Input compilation unit:
CHECK-RELINK-NEXT: TAG_compile_unit
CHECK-RELINK-NOT: TAG
CHECK-RELINK: AT_name {{.*}}bar-relink.c
CHECK-RELINK-NOT: Found valid debug map entry
CHECK-RELINK: Found valid debug map entry: _display 0x0000000000000000 => 0x0000000000003f10
CHECK-RELINK-NEXT: Keeping subprogram DIE:
CHECK-RELINK-NEXT: DW_TAG_subprogram
CHECK-RELINK: DW_AT_name{{.*}}"display"
CHECK-RELINK: Found valid debug map entry: _foo 0x0000000000003f54 => 0x0000000000003f2c
CHECK-RELINK-NEXT: Keeping subprogram DIE:
CHECK-RELINK-NEXT: DW_TAG_subprogram
CHECK-RELINK: DW_AT_name {{.*}}"foo"
CHECK-RELINK-NOT: Found valid debug map entry
CHECK-RELINK: Found valid debug map entry: _foo_unused 0x0000000000003f74 => 0x0000000000003f4c
CHECK-RELINK-NEXT: Keeping subprogram DIE:
CHECK-RELINK-NEXT: DW_TAG_subprogram
CHECK-RELINK: DW_AT_name {{.*}}"foo_unused"
CHECK-RELINK-NOT: Found valid debug map entry
CHECK-RELINK: Found valid debug map entry: _altfoo 0x0000000000003f7c => 0x0000000000003f54
CHECK-RELINK-NEXT: Keeping subprogram DIE:
CHECK-RELINK-NEXT: DW_TAG_subprogram
CHECK-RELINK: DW_AT_name {{.*}}"altfoo"
CHECK-RELINK-NOT: Found valid debug map entry
CHECK-RELINK: Found valid debug map entry: _baz 0x0000000000004000 => 0x0000000000008000
CHECK-RELINK-NEXT: Keeping variable DIE:
CHECK-RELINK-NEXT: DW_TAG_variable
CHECK-RELINK-NEXT: DW_AT_name {{.*}}"baz"
CHECK-RELINK-NOT: Found valid debug map entry
CHECK-RELINK: Found valid debug map entry: _bar 0x0000000000003fa0 => 0x0000000000003f78
CHECK-RELINK-NEXT: Keeping subprogram DIE:
CHECK-RELINK-NEXT: DW_TAG_subprogram
CHECK-RELINK: DW_AT_name {{.*}}"bar"
================================= Two level relink ================================
CHECK-RELINK-TWO: DEBUG MAP OBJECT: {{.*}}proxy-relink.dylib
CHECK-RELINK-TWO: Input compilation unit:
CHECK-RELINK-TWO-NEXT: TAG_compile_unit
CHECK-RELINK-TWO-NOT: TAG
CHECK-RELINK-TWO: AT_name {{.*}}two-level-relink.macho.arm64.c
CHECK-RELINK-TWO: Input compilation unit:
CHECK-RELINK-TWO-NEXT: TAG_compile_unit
CHECK-RELINK-TWO-NOT: TAG
CHECK-RELINK-TWO: AT_name {{.*}}bar-relink.c
CHECK-RELINK-TWO: DW_AT_APPLE_origin {{.*}}/path/to/bar-relink.dylib
CHECK-RELINK-TWO: Input compilation unit:
CHECK-RELINK-TWO-NEXT: TAG_compile_unit
CHECK-RELINK-TWO-NOT: TAG
CHECK-RELINK-TWO: AT_name {{.*}}foo-relink.c
CHECK-RELINK-TWO: DW_AT_APPLE_origin {{.*}}/path/to/foo-relink.dylib
CHECK-RELINK-TWO: Input compilation unit:
CHECK-RELINK-TWO-NEXT: TAG_compile_unit
CHECK-RELINK-TWO-NOT: TAG
CHECK-RELINK-TWO: AT_name {{.*}}altfoo-relink.c
CHECK-RELINK-TWO: DW_AT_APPLE_origin {{.*}}/path/to/foo-relink.dylib
CHECK-RELINK-TWO-NOT: Found valid debug map entry
CHECK-RELINK-TWO: Found valid debug map entry: _display 0x0000000000003f1c => 0x0000000000003f1c
CHECK-RELINK-TWO-NEXT: Keeping subprogram DIE:
CHECK-RELINK-TWO-NEXT: DW_TAG_subprogram
CHECK-RELINK-TWO: DW_AT_name{{.*}}"display"
CHECK-RELINK-TWO-NOT: Found valid debug map entry
CHECK-RELINK-TWO: Found valid debug map entry: _baz 0x0000000000008000 => 0x0000000000008000
CHECK-RELINK-TWO-NEXT: Keeping variable DIE:
CHECK-RELINK-TWO-NEXT: DW_TAG_variable
CHECK-RELINK-TWO-NEXT: DW_AT_name {{.*}}"baz"
CHECK-RELINK-TWO-NOT: Found valid debug map entry
CHECK-RELINK-TWO: Found valid debug map entry: _bar 0x0000000000003f38 => 0x0000000000003f38
CHECK-RELINK-TWO-NEXT: Keeping subprogram DIE:
CHECK-RELINK-TWO-NEXT: DW_TAG_subprogram
CHECK-RELINK-TWO: DW_AT_name {{.*}}"bar"
CHECK-RELINK-TWO: Found valid debug map entry: _foo 0x0000000000003f40 => 0x0000000000003f40
CHECK-RELINK-TWO-NEXT: Keeping subprogram DIE:
CHECK-RELINK-TWO-NEXT: DW_TAG_subprogram
CHECK-RELINK-TWO: DW_AT_name {{.*}}"foo"
CHECK-RELINK-TWO-NOT: Found valid debug map entry
CHECK-RELINK-TWO: Found valid debug map entry: _altfoo 0x0000000000003f64 => 0x0000000000003f64
CHECK-RELINK-TWO-NEXT: Keeping subprogram DIE:
CHECK-RELINK-TWO-NEXT: DW_TAG_subprogram
CHECK-RELINK-TWO: DW_AT_name {{.*}}"altfoo"
================================= Build variants relink ================================
CHECK-RELINK-VARIANT: DEBUG MAP OBJECT: {{.*}}basic-relink.macho.arm64.o
CHECK-RELINK-VARIANT: DEBUG MAP OBJECT: {{.*}}foo-relink-variant_debug.dylib
CHECK-RELINK-VARIANT: DEBUG MAP OBJECT: {{.*}}bar-relink-variant.dylib

View File

@ -7,9 +7,7 @@ HELP-NOT: -reverse-iterate
HELP: Dsymutil Options:
CHECK: -accelerator
CHECK: -arch <arch>
CHECK: -build-variant-suffix <suffix=buildvariant>
CHECK: -dump-debug-map
CHECK: -D <path>
CHECK: -fat64
CHECK: -flat
CHECK: -gen-reproducer

View File

@ -30,7 +30,6 @@ add_llvm_tool(dsymutil
MachODebugMapParser.cpp
MachOUtils.cpp
Reproducer.cpp
RelocationMap.cpp
SymbolMap.cpp
DEPENDS

View File

@ -45,11 +45,6 @@ DebugMapObject::DebugMapObject(StringRef ObjectFilename,
bool DebugMapObject::addSymbol(StringRef Name,
std::optional<uint64_t> ObjectAddress,
uint64_t LinkedAddress, uint32_t Size) {
if (Symbols.count(Name)) {
// Symbol was previously added.
return true;
}
auto InsertResult = Symbols.insert(
std::make_pair(Name, SymbolMapping(ObjectAddress, LinkedAddress, Size)));
@ -58,12 +53,6 @@ bool DebugMapObject::addSymbol(StringRef Name,
return InsertResult.second;
}
void DebugMapObject::setRelocationMap(dsymutil::RelocationMap &RM) {
RelocationMap.emplace(RM);
}
void DebugMapObject::setInstallName(StringRef IN) { InstallName.emplace(IN); }
void DebugMapObject::print(raw_ostream &OS) const {
OS << getObjectFilename() << ":\n";
// Sort the symbols in alphabetical order, like llvm-nm (and to get
@ -169,8 +158,8 @@ struct MappingTraits<dsymutil::DebugMapObject>::YamlDMO {
std::vector<dsymutil::DebugMapObject::YAMLSymbolMapping> Entries;
};
void MappingTraits<std::pair<std::string, SymbolMapping>>::mapping(
IO &io, std::pair<std::string, SymbolMapping> &s) {
void MappingTraits<std::pair<std::string, DebugMapObject::SymbolMapping>>::
mapping(IO &io, std::pair<std::string, DebugMapObject::SymbolMapping> &s) {
io.mapRequired("sym", s.first);
io.mapOptional("objAddr", s.second.ObjectAddress);
io.mapRequired("binAddr", s.second.BinaryAddress);
@ -286,13 +275,7 @@ MappingTraits<dsymutil::DebugMapObject>::YamlDMO::denormalize(IO &IO) {
}
}
uint8_t Type = MachO::N_OSO;
if (Path.endswith(".dylib")) {
// FIXME: find a more resilient way
Type = MachO::N_LIB;
}
dsymutil::DebugMapObject Res(Path, sys::toTimePoint(Timestamp), Type);
dsymutil::DebugMapObject Res(Path, sys::toTimePoint(Timestamp), MachO::N_OSO);
for (auto &Entry : Entries) {
auto &Mapping = Entry.second;
std::optional<uint64_t> ObjAddress;

View File

@ -21,7 +21,6 @@
#ifndef LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
#define LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
#include "RelocationMap.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@ -135,6 +134,22 @@ public:
/// linked binary for all the linked atoms in this object file.
class DebugMapObject {
public:
struct SymbolMapping {
std::optional<yaml::Hex64> ObjectAddress;
yaml::Hex64 BinaryAddress;
yaml::Hex32 Size;
SymbolMapping(std::optional<uint64_t> ObjectAddr, uint64_t BinaryAddress,
uint32_t Size)
: BinaryAddress(BinaryAddress), Size(Size) {
if (ObjectAddr)
ObjectAddress = *ObjectAddr;
}
/// For YAML IO support
SymbolMapping() = default;
};
using YAMLSymbolMapping = std::pair<std::string, SymbolMapping>;
using DebugMapEntry = StringMapEntry<SymbolMapping>;
@ -167,16 +182,6 @@ public:
}
const std::vector<std::string> &getWarnings() const { return Warnings; }
const std::optional<RelocationMap> &getRelocationMap() const {
return RelocationMap;
}
void setRelocationMap(dsymutil::RelocationMap &RM);
const std::optional<std::string> &getInstallName() const {
return InstallName;
}
void setInstallName(StringRef IN);
void print(raw_ostream &OS) const;
#ifndef NDEBUG
void dump() const;
@ -195,9 +200,6 @@ private:
DenseMap<uint64_t, DebugMapEntry *> AddressToMapping;
uint8_t Type;
std::optional<RelocationMap> RelocationMap;
std::optional<std::string> InstallName;
std::vector<std::string> Warnings;
/// For YAMLIO support.
@ -223,8 +225,10 @@ namespace yaml {
using namespace llvm::dsymutil;
template <> struct MappingTraits<std::pair<std::string, SymbolMapping>> {
static void mapping(IO &io, std::pair<std::string, SymbolMapping> &s);
template <>
struct MappingTraits<std::pair<std::string, DebugMapObject::SymbolMapping>> {
static void mapping(IO &io,
std::pair<std::string, DebugMapObject::SymbolMapping> &s);
static const bool flow = true;
};
@ -233,6 +237,12 @@ template <> struct MappingTraits<dsymutil::DebugMapObject> {
static void mapping(IO &io, dsymutil::DebugMapObject &DMO);
};
template <> struct ScalarTraits<Triple> {
static void output(const Triple &val, void *, raw_ostream &out);
static StringRef input(StringRef scalar, void *, Triple &value);
static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
};
template <>
struct SequenceTraits<std::vector<std::unique_ptr<dsymutil::DebugMapObject>>> {
static size_t

View File

@ -189,44 +189,6 @@ static Error remarksErrorHandler(const DebugMapObject &DMO,
return createFileError(FE->getFileName(), std::move(NewE));
}
template <typename OutDwarfFile, typename AddressMap>
Error DwarfLinkerForBinary::emitRelocations(
const DebugMap &DM,
std::vector<ObjectWithRelocMap<OutDwarfFile>> &ObjectsForLinking) {
// Return early if the "Resources" directory is not being written to.
if (!Options.ResourceDir)
return Error::success();
RelocationMap RM(DM.getTriple(), DM.getBinaryPath());
for (auto &Obj : ObjectsForLinking) {
if (!Obj.OutRelocs->isInitialized())
continue;
Obj.OutRelocs->addValidRelocs(RM);
}
SmallString<128> InputPath;
SmallString<128> Path;
// Create the "Relocations" directory in the "Resources" directory, and
// create an architecture-specific directory in the "Relocations" directory.
StringRef ArchName = Triple::getArchName(RM.getTriple().getArch(),
RM.getTriple().getSubArch());
sys::path::append(Path, *Options.ResourceDir, "Relocations", ArchName);
if (std::error_code EC = sys::fs::create_directories(Path.str(), true,
sys::fs::perms::all_all))
return errorCodeToError(EC);
// Append the file name.
sys::path::append(Path, sys::path::filename(DM.getBinaryPath()));
Path.append(".yml");
std::error_code EC;
raw_fd_ostream OS(Path.str(), EC, sys::fs::OF_Text);
if (EC)
return errorCodeToError(EC);
RM.print(OS);
return Error::success();
}
static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath,
StringRef ArchName, const remarks::RemarkLinker &RL) {
@ -267,31 +229,30 @@ static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath,
}
template <typename OutDWARFFile, typename AddressesMap>
ErrorOr<std::unique_ptr<OutDWARFFile>> DwarfLinkerForBinary::loadObject(
const DebugMapObject &Obj, const DebugMap &DebugMap,
remarks::RemarkLinker &RL,
std::shared_ptr<DwarfLinkerForBinaryRelocationMap> DLBRM) {
ErrorOr<std::unique_ptr<OutDWARFFile>>
DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj,
const DebugMap &DebugMap,
remarks::RemarkLinker &RL) {
auto ErrorOrObj = loadObject(Obj, DebugMap.getTriple());
std::unique_ptr<OutDWARFFile> Res;
if (ErrorOrObj) {
auto Context = DWARFContext::create(
*ErrorOrObj, DWARFContext::ProcessDebugRelocations::Process, nullptr,
"",
[&](Error Err) {
handleAllErrors(std::move(Err), [&](ErrorInfoBase &Info) {
reportError(Info.message());
});
},
[&](Error Warning) {
handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) {
reportWarning(Info.message());
});
});
DLBRM->init(*Context);
Res = std::make_unique<OutDWARFFile>(
Obj.getObjectFilename(), std::move(Context),
std::make_unique<AddressesMap>(*this, *ErrorOrObj, Obj, DLBRM),
Obj.getObjectFilename(),
DWARFContext::create(
*ErrorOrObj, DWARFContext::ProcessDebugRelocations::Process,
nullptr, "",
[&](Error Err) {
handleAllErrors(std::move(Err), [&](ErrorInfoBase &Info) {
reportError(Info.message());
});
},
[&](Error Warning) {
handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) {
reportWarning(Info.message());
});
}),
std::make_unique<AddressesMap>(*this, *ErrorOrObj, Obj),
[&](StringRef FileName) { BinHolder.eraseObjectEntry(FileName); });
Error E = RL.link(*ErrorOrObj);
@ -653,7 +614,7 @@ template <typename Linker, typename OutDwarfFile, typename AddressMap>
bool DwarfLinkerForBinary::linkImpl(
const DebugMap &Map, typename Linker::OutputFileType ObjectType) {
std::vector<ObjectWithRelocMap<OutDwarfFile>> ObjectsForLinking;
std::vector<std::unique_ptr<OutDwarfFile>> ObjectsForLinking;
DebugMap DebugMap(Map.getTriple(), Map.getBinaryPath());
@ -707,12 +668,10 @@ bool DwarfLinkerForBinary::linkImpl(
auto &Obj = DebugMap.addDebugMapObject(
Path, sys::TimePoint<std::chrono::seconds>(), MachO::N_OSO);
auto DLBRelocMap = std::make_shared<DwarfLinkerForBinaryRelocationMap>();
if (ErrorOr<std::unique_ptr<OutDwarfFile>> ErrorOrObj =
loadObject<OutDwarfFile, AddressMap>(Obj, DebugMap, RL,
DLBRelocMap)) {
ObjectsForLinking.emplace_back(std::move(*ErrorOrObj), DLBRelocMap);
return *ObjectsForLinking.back().Object;
loadObject<OutDwarfFile, AddressMap>(Obj, DebugMap, RL)) {
ObjectsForLinking.emplace_back(std::move(*ErrorOrObj));
return *ObjectsForLinking.back();
} else {
// Try and emit more helpful warnings by applying some heuristics.
StringRef ObjFile = ContainerName;
@ -823,18 +782,15 @@ bool DwarfLinkerForBinary::linkImpl(
continue;
}
auto DLBRelocMap = std::make_shared<DwarfLinkerForBinaryRelocationMap>();
if (ErrorOr<std::unique_ptr<OutDwarfFile>> ErrorOrObj =
loadObject<OutDwarfFile, AddressMap>(*Obj, Map, RL, DLBRelocMap)) {
ObjectsForLinking.emplace_back(std::move(*ErrorOrObj), DLBRelocMap);
GeneralLinker->addObjectFile(*ObjectsForLinking.back().Object, Loader,
loadObject<OutDwarfFile, AddressMap>(*Obj, Map, RL)) {
ObjectsForLinking.emplace_back(std::move(*ErrorOrObj));
GeneralLinker->addObjectFile(*ObjectsForLinking.back(), Loader,
OnCUDieLoaded);
} else {
ObjectsForLinking.push_back(
{std::make_unique<OutDwarfFile>(Obj->getObjectFilename(), nullptr,
nullptr),
DLBRelocMap});
GeneralLinker->addObjectFile(*ObjectsForLinking.back().Object);
ObjectsForLinking.push_back(std::make_unique<OutDwarfFile>(
Obj->getObjectFilename(), nullptr, nullptr));
GeneralLinker->addObjectFile(*ObjectsForLinking.back());
}
}
@ -859,10 +815,6 @@ bool DwarfLinkerForBinary::linkImpl(
if (Options.NoOutput)
return true;
if (Error E =
emitRelocations<OutDwarfFile, AddressMap>(Map, ObjectsForLinking))
return error(toString(std::move(E)));
if (Options.ResourceDir && !ParseableSwiftInterfaces.empty()) {
StringRef ArchName = Triple::getArchTypeName(Map.getTriple().getArch());
if (auto E = copySwiftInterfaces(ArchName))
@ -951,14 +903,12 @@ void DwarfLinkerForBinary::AddressManager<AddressesMapBase>::
continue;
}
if (const auto *Mapping = DMO.lookupSymbol(*SymbolName))
ValidRelocs.emplace_back(Offset64, RelocSize, Addend, Mapping->getKey(),
Mapping->getValue());
ValidRelocs.emplace_back(Offset64, RelocSize, Addend, Mapping);
} else if (const auto *Mapping = DMO.lookupObjectAddress(SymAddress)) {
// Do not store the addend. The addend was the address of the symbol in
// the object file, the address in the binary that is stored in the debug
// map doesn't need to be offset.
ValidRelocs.emplace_back(Offset64, RelocSize, SymOffset,
Mapping->getKey(), Mapping->getValue());
ValidRelocs.emplace_back(Offset64, RelocSize, SymOffset, Mapping);
}
}
}
@ -1016,17 +966,20 @@ bool DwarfLinkerForBinary::AddressManager<AddressesMapBase>::
}
template <typename AddressesMapBase>
std::vector<ValidReloc>
std::vector<
typename DwarfLinkerForBinary::AddressManager<AddressesMapBase>::ValidReloc>
DwarfLinkerForBinary::AddressManager<AddressesMapBase>::getRelocations(
const std::vector<ValidReloc> &Relocs, uint64_t StartPos, uint64_t EndPos) {
std::vector<ValidReloc> Res;
std::vector<
DwarfLinkerForBinary::AddressManager<AddressesMapBase>::ValidReloc>
Res;
auto CurReloc = partition_point(Relocs, [StartPos](const ValidReloc &Reloc) {
return (uint64_t)Reloc.Offset < StartPos;
return Reloc.Offset < StartPos;
});
while (CurReloc != Relocs.end() && CurReloc->Offset >= StartPos &&
(uint64_t)CurReloc->Offset < EndPos) {
CurReloc->Offset < EndPos) {
Res.push_back(*CurReloc);
CurReloc++;
}
@ -1037,12 +990,12 @@ DwarfLinkerForBinary::AddressManager<AddressesMapBase>::getRelocations(
template <typename AddressesMapBase>
void DwarfLinkerForBinary::AddressManager<AddressesMapBase>::printReloc(
const ValidReloc &Reloc) {
const auto &Mapping = Reloc.SymbolMapping;
const auto &Mapping = Reloc.Mapping->getValue();
const uint64_t ObjectAddress = Mapping.ObjectAddress
? uint64_t(*Mapping.ObjectAddress)
: std::numeric_limits<uint64_t>::max();
outs() << "Found valid debug map entry: " << Reloc.SymbolName << "\t"
outs() << "Found valid debug map entry: " << Reloc.Mapping->getKey() << "\t"
<< format("0x%016" PRIx64 " => 0x%016" PRIx64 "\n", ObjectAddress,
uint64_t(Mapping.BinaryAddress));
}
@ -1051,8 +1004,8 @@ template <typename AddressesMapBase>
int64_t DwarfLinkerForBinary::AddressManager<AddressesMapBase>::getRelocValue(
const ValidReloc &Reloc) {
int64_t AddrAdjust = relocate(Reloc);
if (Reloc.SymbolMapping.ObjectAddress)
AddrAdjust -= uint64_t(*Reloc.SymbolMapping.ObjectAddress);
if (Reloc.Mapping->getValue().ObjectAddress)
AddrAdjust -= uint64_t(*Reloc.Mapping->getValue().ObjectAddress);
return AddrAdjust;
}
@ -1163,40 +1116,12 @@ std::optional<int64_t> DwarfLinkerForBinary::AddressManager<
}
}
template <typename AddressesMapBase>
std::optional<StringRef> DwarfLinkerForBinary::AddressManager<
AddressesMapBase>::getLibraryInstallName() {
return LibInstallName;
}
template <typename AddressesMapBase>
uint64_t DwarfLinkerForBinary::AddressManager<AddressesMapBase>::relocate(
const ValidReloc &Reloc) const {
return Reloc.SymbolMapping.BinaryAddress + Reloc.Addend;
return Reloc.Mapping->getValue().BinaryAddress + Reloc.Addend;
}
template <typename AddressesMapBase>
void DwarfLinkerForBinary::AddressManager<
AddressesMapBase>::updateAndSaveValidRelocs(bool IsDWARF5,
uint64_t OriginalUnitOffset,
int64_t LinkedOffset,
uint64_t StartOffset,
uint64_t EndOffset) {
std::vector<ValidReloc> InRelocs =
getRelocations(ValidDebugInfoRelocs, StartOffset, EndOffset);
if (IsDWARF5)
InRelocs = getRelocations(ValidDebugAddrRelocs, StartOffset, EndOffset);
DwarfLinkerRelocMap->updateAndSaveValidRelocs(
IsDWARF5, InRelocs, OriginalUnitOffset, LinkedOffset);
}
template <typename AddressesMapBase>
void DwarfLinkerForBinary::AddressManager<AddressesMapBase>::
updateRelocationsWithUnitOffset(uint64_t OriginalUnitOffset,
uint64_t OutputUnitOffset) {
DwarfLinkerRelocMap->updateRelocationsWithUnitOffset(OriginalUnitOffset,
OutputUnitOffset);
}
/// Apply the valid relocations found by findValidRelocs() to
/// the buffer \p Data, taking into account that Data is at \p BaseOffset
/// in the debug_info section.
@ -1208,7 +1133,6 @@ void DwarfLinkerForBinary::AddressManager<AddressesMapBase>::
template <typename AddressesMapBase>
bool DwarfLinkerForBinary::AddressManager<AddressesMapBase>::applyValidRelocs(
MutableArrayRef<char> Data, uint64_t BaseOffset, bool IsLittleEndian) {
std::vector<ValidReloc> Relocs = getRelocations(
ValidDebugInfoRelocs, BaseOffset, BaseOffset + Data.size());
@ -1224,47 +1148,9 @@ bool DwarfLinkerForBinary::AddressManager<AddressesMapBase>::applyValidRelocs(
assert(CurReloc.Size <= sizeof(Buf));
memcpy(&Data[CurReloc.Offset - BaseOffset], Buf, CurReloc.Size);
}
return Relocs.size() > 0;
}
void DwarfLinkerForBinaryRelocationMap::init(DWARFContext &Context) {
for (const std::unique_ptr<DWARFUnit> &CU : Context.compile_units())
StoredValidDebugInfoRelocsMap.insert(
std::make_pair(CU->getOffset(), std::vector<ValidReloc>()));
// FIXME: Support relocations debug_addr (DWARF5).
}
void DwarfLinkerForBinaryRelocationMap::addValidRelocs(RelocationMap &RM) {
for (const auto &DebugInfoRelocs : StoredValidDebugInfoRelocsMap) {
for (const auto &InfoReloc : DebugInfoRelocs.second)
RM.addRelocationMapEntry(InfoReloc);
}
// FIXME: Support relocations debug_addr (DWARF5).
}
void DwarfLinkerForBinaryRelocationMap::updateRelocationsWithUnitOffset(
uint64_t OriginalUnitOffset, uint64_t OutputUnitOffset) {
std::vector<ValidReloc> &StoredValidDebugInfoRelocs =
StoredValidDebugInfoRelocsMap[OriginalUnitOffset];
for (ValidReloc &R : StoredValidDebugInfoRelocs) {
R.Offset = (uint64_t)R.Offset + OutputUnitOffset;
}
// FIXME: Support relocations debug_addr (DWARF5).
}
void DwarfLinkerForBinaryRelocationMap::updateAndSaveValidRelocs(
bool IsDWARF5, std::vector<ValidReloc> &InRelocs, uint64_t UnitOffset,
int64_t LinkedOffset) {
std::vector<ValidReloc> &OutRelocs =
StoredValidDebugInfoRelocsMap[UnitOffset];
if (IsDWARF5)
OutRelocs = StoredValidDebugAddrRelocsMap[UnitOffset];
for (ValidReloc &R : InRelocs) {
OutRelocs.emplace_back(R.Offset + LinkedOffset, R.Size, R.Addend,
R.SymbolName, R.SymbolMapping);
}
}
} // namespace dsymutil
} // namespace llvm

View File

@ -13,7 +13,6 @@
#include "DebugMap.h"
#include "LinkUtils.h"
#include "MachOUtils.h"
#include "RelocationMap.h"
#include "llvm/DWARFLinker/DWARFLinker.h"
#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
#include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
@ -22,48 +21,10 @@
#include "llvm/Remarks/RemarkFormat.h"
#include "llvm/Remarks/RemarkLinker.h"
#include <mutex>
#include <optional>
namespace llvm {
namespace dsymutil {
/// DwarfLinkerForBinaryRelocationMap contains the logic to handle the
/// relocations and to store them inside an associated RelocationMap.
class DwarfLinkerForBinaryRelocationMap {
public:
void init(DWARFContext &Context);
bool isInitialized() {
return StoredValidDebugInfoRelocsMap.getMemorySize() != 0;
}
void addValidRelocs(RelocationMap &RM);
void updateAndSaveValidRelocs(bool IsDWARF5,
std::vector<ValidReloc> &InRelocs,
uint64_t UnitOffset, int64_t LinkedOffset);
void updateRelocationsWithUnitOffset(uint64_t OriginalUnitOffset,
uint64_t OutputUnitOffset);
/// Map compilation unit offset to the valid relocations to store
/// @{
DenseMap<uint64_t, std::vector<ValidReloc>> StoredValidDebugInfoRelocsMap;
DenseMap<uint64_t, std::vector<ValidReloc>> StoredValidDebugAddrRelocsMap;
/// @}
DwarfLinkerForBinaryRelocationMap() = default;
};
template <typename OutDwarfFile> struct ObjectWithRelocMap {
ObjectWithRelocMap(
std::unique_ptr<OutDwarfFile> Object,
std::shared_ptr<DwarfLinkerForBinaryRelocationMap> OutRelocs)
: Object(std::move(Object)), OutRelocs(OutRelocs) {}
std::unique_ptr<OutDwarfFile> Object;
std::shared_ptr<DwarfLinkerForBinaryRelocationMap> OutRelocs;
};
/// The core of the Dsymutil Dwarf linking logic.
///
/// The link of the dwarf information from the object files will be
@ -106,11 +67,26 @@ private:
/// Keeps track of relocations.
template <typename AddressesMapBase>
class AddressManager : public AddressesMapBase {
struct ValidReloc {
uint64_t Offset;
uint32_t Size;
uint64_t Addend;
const DebugMapObject::DebugMapEntry *Mapping;
ValidReloc(uint64_t Offset, uint32_t Size, uint64_t Addend,
const DebugMapObject::DebugMapEntry *Mapping)
: Offset(Offset), Size(Size), Addend(Addend), Mapping(Mapping) {}
bool operator<(const ValidReloc &RHS) const {
return Offset < RHS.Offset;
}
bool operator<(uint64_t RHS) const { return Offset < RHS; }
};
const DwarfLinkerForBinary &Linker;
/// The valid relocations for the current DebugMapObject.
/// These vectors are sorted by relocation offset.
/// This vector is sorted by relocation offset.
/// {
std::vector<ValidReloc> ValidDebugInfoRelocs;
std::vector<ValidReloc> ValidDebugAddrRelocs;
@ -118,12 +94,6 @@ private:
StringRef SrcFileName;
uint8_t DebugMapObjectType;
std::shared_ptr<DwarfLinkerForBinaryRelocationMap> DwarfLinkerRelocMap;
std::optional<std::string> LibInstallName;
/// Returns list of valid relocations from \p Relocs,
/// between \p StartOffset and \p NextOffset.
///
@ -145,29 +115,9 @@ private:
public:
AddressManager(DwarfLinkerForBinary &Linker, const object::ObjectFile &Obj,
const DebugMapObject &DMO,
std::shared_ptr<DwarfLinkerForBinaryRelocationMap> DLBRM)
: Linker(Linker), SrcFileName(DMO.getObjectFilename()),
DebugMapObjectType(MachO::N_OSO), DwarfLinkerRelocMap(DLBRM) {
if (DMO.getRelocationMap().has_value()) {
DebugMapObjectType = MachO::N_LIB;
LibInstallName.emplace(DMO.getInstallName().value());
const RelocationMap &RM = DMO.getRelocationMap().value();
for (const auto &Reloc : RM.relocations()) {
const auto *DebugMapEntry = DMO.lookupSymbol(Reloc.SymbolName);
if (!DebugMapEntry)
continue;
std::optional<uint64_t> ObjAddress;
ObjAddress.emplace(DebugMapEntry->getValue().ObjectAddress.value());
ValidDebugInfoRelocs.emplace_back(
Reloc.Offset, Reloc.Size, Reloc.Addend, Reloc.SymbolName,
SymbolMapping(ObjAddress, DebugMapEntry->getValue().BinaryAddress,
DebugMapEntry->getValue().Size));
// FIXME: Support relocations debug_addr.
}
} else {
findValidRelocsInDebugSections(Obj, DMO);
}
const DebugMapObject &DMO)
: Linker(Linker), SrcFileName(DMO.getObjectFilename()) {
findValidRelocsInDebugSections(Obj, DMO);
}
~AddressManager() override { clear(); }
@ -208,20 +158,9 @@ private:
std::optional<int64_t>
getSubprogramRelocAdjustment(const DWARFDie &DIE) override;
std::optional<StringRef> getLibraryInstallName() override;
bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
bool IsLittleEndian) override;
bool needToSaveValidRelocs() override { return true; }
void updateAndSaveValidRelocs(bool IsDWARF5, uint64_t OriginalUnitOffset,
int64_t LinkedOffset, uint64_t StartOffset,
uint64_t EndOffset) override;
void updateRelocationsWithUnitOffset(uint64_t OriginalUnitOffset,
uint64_t OutputUnitOffset) override;
void clear() override {
ValidDebugInfoRelocs.clear();
ValidDebugAddrRelocs.clear();
@ -241,11 +180,11 @@ private:
/// Attempt to load a debug object from disk.
ErrorOr<const object::ObjectFile &> loadObject(const DebugMapObject &Obj,
const Triple &triple);
template <typename OutDWARFFile, typename AddressesMap>
ErrorOr<std::unique_ptr<OutDWARFFile>>
loadObject(const DebugMapObject &Obj, const DebugMap &DebugMap,
remarks::RemarkLinker &RL,
std::shared_ptr<DwarfLinkerForBinaryRelocationMap> DLBRM);
ErrorOr<std::unique_ptr<OutDWARFFile>> loadObject(const DebugMapObject &Obj,
const DebugMap &DebugMap,
remarks::RemarkLinker &RL);
void collectRelocationsToApplyToSwiftReflectionSections(
const object::SectionRef &Section, StringRef &Contents,
@ -268,11 +207,6 @@ private:
bool linkImpl(const DebugMap &Map,
typename Linker::OutputFileType ObjectType);
template <typename OutDwarfFile, typename AddressMap>
Error emitRelocations(
const DebugMap &DM,
std::vector<ObjectWithRelocMap<OutDwarfFile>> &ObjectsForLinking);
raw_fd_ostream &OutFile;
BinaryHolder &BinHolder;
LinkOptions Options;

View File

@ -93,12 +93,6 @@ struct LinkOptions {
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
vfs::getRealFileSystem();
/// -build-variant-suffix.
std::string BuildVariantSuffix;
/// Paths where to search for the .dSYM files of merged libraries.
std::vector<std::string> DSYMSearchPaths;
/// Fields used for linking and placing remarks into the .dSYM bundle.
/// @{

View File

@ -9,7 +9,6 @@
#include "BinaryHolder.h"
#include "DebugMap.h"
#include "MachOUtils.h"
#include "RelocationMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Object/MachO.h"
@ -29,13 +28,9 @@ class MachODebugMapParser {
public:
MachODebugMapParser(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
StringRef BinaryPath, ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths,
StringRef PathPrefix = "", StringRef VariantSuffix = "",
bool Verbose = false)
StringRef PathPrefix = "", bool Verbose = false)
: BinaryPath(std::string(BinaryPath)), Archs(Archs.begin(), Archs.end()),
DSYMSearchPaths(DSYMSearchPaths.begin(), DSYMSearchPaths.end()),
PathPrefix(std::string(PathPrefix)),
VariantSuffix(std::string(VariantSuffix)), BinHolder(VFS, Verbose),
PathPrefix(std::string(PathPrefix)), BinHolder(VFS, Verbose),
CurrentDebugMapObject(nullptr), SkipDebugMapObject(false) {}
/// Parses and returns the DebugMaps of the input binary. The binary contains
@ -52,9 +47,7 @@ public:
private:
std::string BinaryPath;
SmallVector<StringRef, 1> Archs;
SmallVector<StringRef, 1> DSYMSearchPaths;
std::string PathPrefix;
std::string VariantSuffix;
/// Owns the MemoryBuffer for the main binary.
BinaryHolder BinHolder;
@ -94,9 +87,6 @@ private:
void
switchToNewDebugMapObject(StringRef Filename,
sys::TimePoint<std::chrono::seconds> Timestamp);
void
switchToNewLibDebugMapObject(StringRef Filename,
sys::TimePoint<std::chrono::seconds> Timestamp);
void resetParserState();
uint64_t getMainBinarySymbolAddress(StringRef Name);
std::vector<StringRef> getMainBinarySymbolNames(uint64_t Value);
@ -186,6 +176,8 @@ void MachODebugMapParser::addCommonSymbols() {
/// everything up to add symbols to the new one.
void MachODebugMapParser::switchToNewDebugMapObject(
StringRef Filename, sys::TimePoint<std::chrono::seconds> Timestamp) {
addCommonSymbols();
resetParserState();
SmallString<80> Path(PathPrefix);
sys::path::append(Path, Filename);
@ -206,138 +198,11 @@ void MachODebugMapParser::switchToNewDebugMapObject(
return;
}
addCommonSymbols();
resetParserState();
CurrentDebugMapObject =
&Result->addDebugMapObject(Path, Timestamp, MachO::N_OSO);
loadCurrentObjectFileSymbols(*Object);
}
/// Create a new DebugMapObject of type MachO::N_LIB.
/// This function resets the state of the parser that was
/// referring to the last object file and sets everything
/// up to add symbols to the new one.
void MachODebugMapParser::switchToNewLibDebugMapObject(
StringRef Filename, sys::TimePoint<std::chrono::seconds> Timestamp) {
if (DSYMSearchPaths.empty()) {
Warning("no dSYM search path was specified");
return;
}
StringRef LeafName = sys::path::filename(Filename);
SmallString<128> VariantLeafName;
SmallString<128> ProductName(LeafName);
// For Framework.framework/Framework and -build-variant-suffix=_debug,
// look in the following order:
// 1) Framework.framework.dSYM/Contents/Resources/DWARF/Framework_debug
// 2) Framework.framework.dSYM/Contents/Resources/DWARF/Framework
//
// For libName.dylib and -build-variant-suffix=_debug,
// look in the following order:
// 1) libName.dylib.dSYM/Contents/Resources/DWARF/libName_debug.dylib
// 2) libName.dylib.dSYM/Contents/Resources/DWARF/libName.dylib
size_t libExt = LeafName.rfind(".dylib");
if (libExt != StringRef::npos) {
if (!VariantSuffix.empty()) {
VariantLeafName.append(LeafName.substr(0, libExt));
VariantLeafName.append(VariantSuffix);
VariantLeafName.append(".dylib");
}
} else {
// Expected to be a framework
ProductName.append(".framework");
if (!VariantSuffix.empty()) {
VariantLeafName.append(LeafName);
VariantLeafName.append(VariantSuffix);
}
}
for (auto DSYMSearchPath : DSYMSearchPaths) {
SmallString<256> Path(DSYMSearchPath);
SmallString<256> FallbackPath(Path);
SmallString<256> DSYMPath(ProductName);
DSYMPath.append(".dSYM");
sys::path::append(DSYMPath, "Contents", "Resources", "DWARF");
if (!VariantSuffix.empty()) {
sys::path::append(Path, DSYMPath, VariantLeafName);
sys::path::append(FallbackPath, DSYMPath, LeafName);
} else {
sys::path::append(Path, DSYMPath, LeafName);
}
auto ObjectEntry = BinHolder.getObjectEntry(Path, Timestamp);
if (!ObjectEntry) {
auto Err = ObjectEntry.takeError();
Warning("unable to open object file: " + toString(std::move(Err)),
Path.str());
if (!VariantSuffix.empty()) {
ObjectEntry = BinHolder.getObjectEntry(FallbackPath, Timestamp);
if (!ObjectEntry) {
auto Err = ObjectEntry.takeError();
Warning("unable to open object file: " + toString(std::move(Err)),
FallbackPath.str());
continue;
}
Path.assign(FallbackPath);
} else {
continue;
}
}
auto Object =
ObjectEntry->getObjectAs<MachOObjectFile>(Result->getTriple());
if (!Object) {
auto Err = Object.takeError();
Warning("unable to open object file: " + toString(std::move(Err)),
Path.str());
continue;
}
if (CurrentDebugMapObject &&
CurrentDebugMapObject->getType() == MachO::N_LIB &&
CurrentDebugMapObject->getObjectFilename().compare(Path.str()) == 0) {
return;
}
addCommonSymbols();
resetParserState();
CurrentDebugMapObject =
&Result->addDebugMapObject(Path, Timestamp, MachO::N_LIB);
CurrentDebugMapObject->setInstallName(Filename);
SmallString<256> RMPath(DSYMSearchPath);
sys::path::append(RMPath, ProductName);
RMPath.append(".dSYM");
StringRef ArchName = Triple::getArchName(Result->getTriple().getArch(),
Result->getTriple().getSubArch());
sys::path::append(RMPath, "Contents", "Resources", "Relocations", ArchName);
sys::path::append(RMPath, LeafName);
RMPath.append(".yml");
const auto &RelocMapPtrOrErr =
RelocationMap::parseYAMLRelocationMap(RMPath, PathPrefix);
if (auto EC = RelocMapPtrOrErr.getError()) {
Warning("cannot parse relocation map file: " + EC.message(),
RMPath.str());
return;
}
CurrentDebugMapObject->setRelocationMap(*RelocMapPtrOrErr->get());
loadCurrentObjectFileSymbols(*Object);
// Found and loaded new dSYM file
return;
}
}
static std::string getArchName(const object::MachOObjectFile &Obj) {
Triple T = Obj.getArchTriple();
return std::string(T.getArchName());
@ -410,39 +275,23 @@ struct DarwinStabName {
const char *Name;
};
const struct DarwinStabName DarwinStabNames[] = {{MachO::N_GSYM, "N_GSYM"},
{MachO::N_FNAME, "N_FNAME"},
{MachO::N_FUN, "N_FUN"},
{MachO::N_STSYM, "N_STSYM"},
{MachO::N_LCSYM, "N_LCSYM"},
{MachO::N_BNSYM, "N_BNSYM"},
{MachO::N_PC, "N_PC"},
{MachO::N_AST, "N_AST"},
{MachO::N_OPT, "N_OPT"},
{MachO::N_RSYM, "N_RSYM"},
{MachO::N_SLINE, "N_SLINE"},
{MachO::N_ENSYM, "N_ENSYM"},
{MachO::N_SSYM, "N_SSYM"},
{MachO::N_SO, "N_SO"},
{MachO::N_OSO, "N_OSO"},
{MachO::N_LIB, "N_LIB"},
{MachO::N_LSYM, "N_LSYM"},
{MachO::N_BINCL, "N_BINCL"},
{MachO::N_SOL, "N_SOL"},
{MachO::N_PARAMS, "N_PARAM"},
{MachO::N_VERSION, "N_VERS"},
{MachO::N_OLEVEL, "N_OLEV"},
{MachO::N_PSYM, "N_PSYM"},
{MachO::N_EINCL, "N_EINCL"},
{MachO::N_ENTRY, "N_ENTRY"},
{MachO::N_LBRAC, "N_LBRAC"},
{MachO::N_EXCL, "N_EXCL"},
{MachO::N_RBRAC, "N_RBRAC"},
{MachO::N_BCOMM, "N_BCOMM"},
{MachO::N_ECOMM, "N_ECOMM"},
{MachO::N_ECOML, "N_ECOML"},
{MachO::N_LENG, "N_LENG"},
{0, nullptr}};
const struct DarwinStabName DarwinStabNames[] = {
{MachO::N_GSYM, "N_GSYM"}, {MachO::N_FNAME, "N_FNAME"},
{MachO::N_FUN, "N_FUN"}, {MachO::N_STSYM, "N_STSYM"},
{MachO::N_LCSYM, "N_LCSYM"}, {MachO::N_BNSYM, "N_BNSYM"},
{MachO::N_PC, "N_PC"}, {MachO::N_AST, "N_AST"},
{MachO::N_OPT, "N_OPT"}, {MachO::N_RSYM, "N_RSYM"},
{MachO::N_SLINE, "N_SLINE"}, {MachO::N_ENSYM, "N_ENSYM"},
{MachO::N_SSYM, "N_SSYM"}, {MachO::N_SO, "N_SO"},
{MachO::N_OSO, "N_OSO"}, {MachO::N_LSYM, "N_LSYM"},
{MachO::N_BINCL, "N_BINCL"}, {MachO::N_SOL, "N_SOL"},
{MachO::N_PARAMS, "N_PARAM"}, {MachO::N_VERSION, "N_VERS"},
{MachO::N_OLEVEL, "N_OLEV"}, {MachO::N_PSYM, "N_PSYM"},
{MachO::N_EINCL, "N_EINCL"}, {MachO::N_ENTRY, "N_ENTRY"},
{MachO::N_LBRAC, "N_LBRAC"}, {MachO::N_EXCL, "N_EXCL"},
{MachO::N_RBRAC, "N_RBRAC"}, {MachO::N_BCOMM, "N_BCOMM"},
{MachO::N_ECOMM, "N_ECOMM"}, {MachO::N_ECOML, "N_ECOML"},
{MachO::N_LENG, "N_LENG"}, {0, nullptr}};
static const char *getDarwinStabString(uint8_t NType) {
for (unsigned i = 0; DarwinStabNames[i].Name; i++) {
@ -628,25 +477,13 @@ void MachODebugMapParser::handleStabSymbolTableEntry(
const char *Name = &MainBinaryStrings.data()[StringIndex];
// An N_LIB entry represents the start of a new library file description.
if (Type == MachO::N_LIB) {
switchToNewLibDebugMapObject(Name, sys::toTimePoint(Value));
return;
}
// An N_OSO entry represents the start of a new object file description.
// If an N_LIB entry was present, this is parsed only if the library
// dSYM file could not be found.
if (Type == MachO::N_OSO) {
if (!CurrentDebugMapObject ||
CurrentDebugMapObject->getType() != MachO::N_LIB) {
if (Duplicates.count(OSO(Name, Value))) {
SkipDebugMapObject = true;
return;
}
switchToNewDebugMapObject(Name, sys::toTimePoint(Value));
if (Duplicates.count(OSO(Name, Value))) {
SkipDebugMapObject = true;
return;
}
return;
return switchToNewDebugMapObject(Name, sys::toTimePoint(Value));
}
if (SkipDebugMapObject)
@ -857,23 +694,18 @@ namespace dsymutil {
llvm::ErrorOr<std::vector<std::unique_ptr<DebugMap>>>
parseDebugMap(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
StringRef InputFile, ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath,
StringRef VariantSuffix, bool Verbose, bool InputIsYAML) {
StringRef PrependPath, bool Verbose, bool InputIsYAML) {
if (InputIsYAML)
return DebugMap::parseYAMLDebugMap(InputFile, PrependPath, Verbose);
MachODebugMapParser Parser(VFS, InputFile, Archs, DSYMSearchPaths,
PrependPath, VariantSuffix, Verbose);
MachODebugMapParser Parser(VFS, InputFile, Archs, PrependPath, Verbose);
return Parser.parse();
}
bool dumpStab(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
StringRef InputFile, ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath,
StringRef VariantSuffix) {
MachODebugMapParser Parser(VFS, InputFile, Archs, DSYMSearchPaths,
PrependPath, VariantSuffix, false);
StringRef PrependPath) {
MachODebugMapParser Parser(VFS, InputFile, Archs, PrependPath, false);
return Parser.dumpStab();
}
} // namespace dsymutil

View File

@ -201,14 +201,3 @@ def linker: Separate<["--", "-"], "linker">,
HelpText<"Specify the desired type of DWARF linker. Defaults to 'apple'">,
Group<grp_general>;
def: Joined<["--", "-"], "linker=">, Alias<linker>;
def build_variant_suffix: Separate<["--", "-"], "build-variant-suffix">,
MetaVarName<"<suffix=buildvariant>">,
HelpText<"Specify the build variant suffix used to build the executabe file.">,
Group<grp_general>;
def: Joined<["--", "-"], "build-variant-suffix=">, Alias<build_variant_suffix>;
def dsym_search_path: Separate<["-", "--"], "D">,
MetaVarName<"<path>">,
HelpText<"Specify a directory that contain dSYM files to search for.">,
Group<grp_general>;

View File

@ -1,92 +0,0 @@
//===- tools/dsymutil/RelocationMap.cpp - Relocation map representation---===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "RelocationMap.h"
namespace llvm {
namespace dsymutil {
void RelocationMap::print(raw_ostream &OS) const {
yaml::Output yout(OS, /* Ctxt = */ nullptr, /* WrapColumn = */ 0);
yout << const_cast<RelocationMap &>(*this);
}
#ifndef NDEBUG
void RelocationMap::dump() const { print(errs()); }
#endif
void RelocationMap::addRelocationMapEntry(const ValidReloc &Relocation) {
Relocations.push_back(Relocation);
}
namespace {
struct YAMLContext {
StringRef PrependPath;
Triple BinaryTriple;
};
} // end anonymous namespace
ErrorOr<std::unique_ptr<RelocationMap>>
RelocationMap::parseYAMLRelocationMap(StringRef InputFile,
StringRef PrependPath) {
auto ErrOrFile = MemoryBuffer::getFileOrSTDIN(InputFile);
if (auto Err = ErrOrFile.getError())
return Err;
YAMLContext Ctxt;
Ctxt.PrependPath = PrependPath;
std::unique_ptr<RelocationMap> Result;
yaml::Input yin((*ErrOrFile)->getBuffer(), &Ctxt);
yin >> Result;
if (auto EC = yin.error())
return EC;
return std::move(Result);
}
} // end namespace dsymutil
namespace yaml {
void MappingTraits<dsymutil::ValidReloc>::mapping(IO &io,
dsymutil::ValidReloc &VR) {
io.mapRequired("offset", VR.Offset);
io.mapRequired("size", VR.Size);
io.mapRequired("addend", VR.Addend);
io.mapRequired("symName", VR.SymbolName);
io.mapOptional("symObjAddr", VR.SymbolMapping.ObjectAddress);
io.mapRequired("symBinAddr", VR.SymbolMapping.BinaryAddress);
io.mapRequired("symSize", VR.SymbolMapping.Size);
}
void MappingTraits<dsymutil::RelocationMap>::mapping(
IO &io, dsymutil::RelocationMap &RM) {
io.mapRequired("triple", RM.BinaryTriple);
io.mapRequired("binary-path", RM.BinaryPath);
if (void *Ctxt = io.getContext())
reinterpret_cast<YAMLContext *>(Ctxt)->BinaryTriple = RM.BinaryTriple;
io.mapRequired("relocations", RM.Relocations);
}
void MappingTraits<std::unique_ptr<dsymutil::RelocationMap>>::mapping(
IO &io, std::unique_ptr<dsymutil::RelocationMap> &RM) {
if (!RM)
RM.reset(new RelocationMap());
io.mapRequired("triple", RM->BinaryTriple);
io.mapRequired("binary-path", RM->BinaryPath);
if (void *Ctxt = io.getContext())
reinterpret_cast<YAMLContext *>(Ctxt)->BinaryTriple = RM->BinaryTriple;
io.mapRequired("relocations", RM->Relocations);
}
} // end namespace yaml
} // end namespace llvm

View File

@ -1,160 +0,0 @@
//===- tools/dsymutil/RelocationMap.h -------------------------- *- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \file
///
/// This file contains the class declaration of the RelocationMap
/// entity. RelocationMap lists all the relocations of all the
/// atoms used in the object files linked together to
/// produce an executable.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_DSYMUTIL_RELOCATIONMAP_H
#define LLVM_TOOLS_DSYMUTIL_RELOCATIONMAP_H
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/TargetParser/Triple.h"
#include <optional>
#include <string>
#include <vector>
namespace llvm {
class raw_ostream;
namespace dsymutil {
struct SymbolMapping {
std::optional<yaml::Hex64> ObjectAddress;
yaml::Hex64 BinaryAddress;
yaml::Hex32 Size;
SymbolMapping(std::optional<uint64_t> ObjectAddr, uint64_t BinaryAddress,
uint32_t Size)
: BinaryAddress(BinaryAddress), Size(Size) {
if (ObjectAddr)
ObjectAddress = *ObjectAddr;
}
/// For YAML IO support
SymbolMapping() = default;
};
/// ValidReloc represents one relocation entry described by the RelocationMap.
/// It contains a list of DWARF relocations to apply to a linked binary.
class ValidReloc {
public:
yaml::Hex64 Offset;
yaml::Hex32 Size;
yaml::Hex64 Addend;
std::string SymbolName;
SymbolMapping SymbolMapping;
struct SymbolMapping getSymbolMapping() const { return SymbolMapping; }
ValidReloc(uint64_t Offset, uint32_t Size, uint64_t Addend,
StringRef SymbolName, struct SymbolMapping SymbolMapping)
: Offset(Offset), Size(Size), Addend(Addend), SymbolName(SymbolName),
SymbolMapping(SymbolMapping) {}
bool operator<(const ValidReloc &RHS) const { return Offset < RHS.Offset; }
/// For YAMLIO support.
ValidReloc() = default;
};
/// The RelocationMap object stores the list of relocation entries for a binary
class RelocationMap {
Triple BinaryTriple;
std::string BinaryPath;
using RelocContainer = std::vector<ValidReloc>;
RelocContainer Relocations;
/// For YAML IO support.
///@{
friend yaml::MappingTraits<std::unique_ptr<RelocationMap>>;
friend yaml::MappingTraits<RelocationMap>;
RelocationMap() = default;
///@}
public:
RelocationMap(const Triple &BinaryTriple, StringRef BinaryPath)
: BinaryTriple(BinaryTriple), BinaryPath(std::string(BinaryPath)) {}
using const_iterator = RelocContainer::const_iterator;
iterator_range<const_iterator> relocations() const {
return make_range(begin(), end());
}
const_iterator begin() const { return Relocations.begin(); }
const_iterator end() const { return Relocations.end(); }
size_t getNumberOfEntries() const { return Relocations.size(); }
/// This function adds a ValidReloc to the list owned by this
/// relocation map.
void addRelocationMapEntry(const ValidReloc &Relocation);
const Triple &getTriple() const { return BinaryTriple; }
StringRef getBinaryPath() const { return BinaryPath; }
void print(raw_ostream &OS) const;
#ifndef NDEBUG
void dump() const;
#endif
/// Read a relocation map from \a InputFile.
static ErrorOr<std::unique_ptr<RelocationMap>>
parseYAMLRelocationMap(StringRef InputFile, StringRef PrependPath);
};
} // end namespace dsymutil
} // end namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(dsymutil::ValidReloc)
namespace llvm {
namespace yaml {
using namespace llvm::dsymutil;
template <> struct MappingTraits<dsymutil::ValidReloc> {
static void mapping(IO &io, dsymutil::ValidReloc &VR);
static const bool flow = true;
};
template <> struct MappingTraits<dsymutil::RelocationMap> {
struct YamlRM;
static void mapping(IO &io, dsymutil::RelocationMap &RM);
};
template <> struct MappingTraits<std::unique_ptr<dsymutil::RelocationMap>> {
struct YamlRM;
static void mapping(IO &io, std::unique_ptr<dsymutil::RelocationMap> &RM);
};
template <> struct ScalarTraits<Triple> {
static void output(const Triple &val, void *, raw_ostream &out);
static StringRef input(StringRef scalar, void *, Triple &value);
static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
};
} // end namespace yaml
} // end namespace llvm
#endif // LLVM_TOOLS_DSYMUTIL_RELOCATIONMAP_H

View File

@ -398,12 +398,6 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) {
Options.LinkOpts.RemarksKeepAll =
!Args.hasArg(OPT_remarks_drop_without_debug);
if (opt::Arg *BuildVariantSuffix = Args.getLastArg(OPT_build_variant_suffix))
Options.LinkOpts.BuildVariantSuffix = BuildVariantSuffix->getValue();
for (auto *SearchPath : Args.filtered(OPT_dsym_search_path))
Options.LinkOpts.DSYMSearchPaths.push_back(SearchPath->getValue());
if (Error E = verifyOptions(Options))
return std::move(E);
return Options;
@ -676,18 +670,15 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
// Dump the symbol table for each input file and requested arch
if (Options.DumpStab) {
if (!dumpStab(Options.LinkOpts.VFS, InputFile, Options.Archs,
Options.LinkOpts.DSYMSearchPaths,
Options.LinkOpts.PrependPath,
Options.LinkOpts.BuildVariantSuffix))
Options.LinkOpts.PrependPath))
return EXIT_FAILURE;
continue;
}
auto DebugMapPtrsOrErr = parseDebugMap(
Options.LinkOpts.VFS, InputFile, Options.Archs,
Options.LinkOpts.DSYMSearchPaths, Options.LinkOpts.PrependPath,
Options.LinkOpts.BuildVariantSuffix, Options.LinkOpts.Verbose,
Options.InputIsYAMLDebugMap);
auto DebugMapPtrsOrErr =
parseDebugMap(Options.LinkOpts.VFS, InputFile, Options.Archs,
Options.LinkOpts.PrependPath, Options.LinkOpts.Verbose,
Options.InputIsYAMLDebugMap);
if (auto EC = DebugMapPtrsOrErr.getError()) {
WithColor::error() << "cannot parse the debug map for '" << InputFile

View File

@ -35,14 +35,12 @@ namespace dsymutil {
ErrorOr<std::vector<std::unique_ptr<DebugMap>>>
parseDebugMap(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
StringRef InputFile, ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath,
StringRef VariantSuffix, bool Verbose, bool InputIsYAML);
StringRef PrependPath, bool Verbose, bool InputIsYAML);
/// Dump the symbol table.
bool dumpStab(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
StringRef InputFile, ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath = "",
StringRef VariantSuffix = "");
StringRef PrependPath = "");
} // end namespace dsymutil
} // end namespace llvm

View File

@ -132,23 +132,11 @@ public:
return std::nullopt;
}
std::optional<StringRef> getLibraryInstallName() override {
return std::nullopt;
}
bool applyValidRelocs(MutableArrayRef<char>, uint64_t, bool) override {
// no need to apply relocations to the linked binary.
return false;
}
bool needToSaveValidRelocs() override { return false; }
void updateAndSaveValidRelocs(bool, uint64_t, int64_t, uint64_t,
uint64_t) override {}
void updateRelocationsWithUnitOffset(uint64_t OriginalUnitOffset,
uint64_t OutputUnitOffset) override {}
void clear() override {}
protected:

View File

@ -561,22 +561,37 @@ struct DarwinStabName {
const char *Name;
};
const struct DarwinStabName DarwinStabNames[] = {
{MachO::N_GSYM, "GSYM"}, {MachO::N_FNAME, "FNAME"},
{MachO::N_FUN, "FUN"}, {MachO::N_STSYM, "STSYM"},
{MachO::N_LCSYM, "LCSYM"}, {MachO::N_BNSYM, "BNSYM"},
{MachO::N_PC, "PC"}, {MachO::N_AST, "AST"},
{MachO::N_OPT, "OPT"}, {MachO::N_RSYM, "RSYM"},
{MachO::N_SLINE, "SLINE"}, {MachO::N_ENSYM, "ENSYM"},
{MachO::N_SSYM, "SSYM"}, {MachO::N_SO, "SO"},
{MachO::N_OSO, "OSO"}, {MachO::N_LIB, "LIB"},
{MachO::N_LSYM, "LSYM"}, {MachO::N_BINCL, "BINCL"},
{MachO::N_SOL, "SOL"}, {MachO::N_PARAMS, "PARAM"},
{MachO::N_VERSION, "VERS"}, {MachO::N_OLEVEL, "OLEV"},
{MachO::N_PSYM, "PSYM"}, {MachO::N_EINCL, "EINCL"},
{MachO::N_ENTRY, "ENTRY"}, {MachO::N_LBRAC, "LBRAC"},
{MachO::N_EXCL, "EXCL"}, {MachO::N_RBRAC, "RBRAC"},
{MachO::N_BCOMM, "BCOMM"}, {MachO::N_ECOMM, "ECOMM"},
{MachO::N_ECOML, "ECOML"}, {MachO::N_LENG, "LENG"},
{MachO::N_GSYM, "GSYM"},
{MachO::N_FNAME, "FNAME"},
{MachO::N_FUN, "FUN"},
{MachO::N_STSYM, "STSYM"},
{MachO::N_LCSYM, "LCSYM"},
{MachO::N_BNSYM, "BNSYM"},
{MachO::N_PC, "PC"},
{MachO::N_AST, "AST"},
{MachO::N_OPT, "OPT"},
{MachO::N_RSYM, "RSYM"},
{MachO::N_SLINE, "SLINE"},
{MachO::N_ENSYM, "ENSYM"},
{MachO::N_SSYM, "SSYM"},
{MachO::N_SO, "SO"},
{MachO::N_OSO, "OSO"},
{MachO::N_LSYM, "LSYM"},
{MachO::N_BINCL, "BINCL"},
{MachO::N_SOL, "SOL"},
{MachO::N_PARAMS, "PARAM"},
{MachO::N_VERSION, "VERS"},
{MachO::N_OLEVEL, "OLEV"},
{MachO::N_PSYM, "PSYM"},
{MachO::N_EINCL, "EINCL"},
{MachO::N_ENTRY, "ENTRY"},
{MachO::N_LBRAC, "LBRAC"},
{MachO::N_EXCL, "EXCL"},
{MachO::N_RBRAC, "RBRAC"},
{MachO::N_BCOMM, "BCOMM"},
{MachO::N_ECOMM, "ECOMM"},
{MachO::N_ECOML, "ECOML"},
{MachO::N_LENG, "LENG"},
};
static const char *getDarwinStabString(uint8_t NType) {