diff options
author | Alpha Abdoulaye <aabdoulaye@apple.com> | 2023-10-24 10:36:57 -0700 |
---|---|---|
committer | Jonas Devlieghere <jonas@devlieghere.com> | 2023-10-24 10:39:08 -0700 |
commit | 122c89b271af30b86536cad7bac64ea9c56615ed (patch) | |
tree | 3c76f319549c6a0bbdce795dcaadfc6df1fd2166 /llvm/lib | |
parent | 4c28e666a75805cf453c0d4ed153bfbc779c45c5 (diff) | |
download | llvm-122c89b271af30b86536cad7bac64ea9c56615ed.zip llvm-122c89b271af30b86536cad7bac64ea9c56615ed.tar.gz llvm-122c89b271af30b86536cad7bac64ea9c56615ed.tar.bz2 |
[dsymutil] Add support for mergeable libraries
This adds support in dsymutil for mergeable libraries [1].
dsymutil reads a new stab emitted by ld, allowing it to operate on
dynamic libraries instead of object files. It also now loads the DWARF
files associated to the libraries, and build the debug map for each
binary from the list of symbols exported by the library. For each Debug
Map Object, there is a new associated Relocation Map which is serialized
from the information retrieved in the original debug_info (or
debug_addr) section of the .o file.
The final DWARF file has multiple compile units, so the offsets
information of the relocations are adjusted relatively to the compile
unit they will end up belonging to, inside the final linked DWARF file.
[1] https://developer.apple.com/documentation/xcode/configuring-your-project-to-use-mergeable-libraries
Differential revision: https://reviews.llvm.org/D158124
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/DWARFLinker/DWARFLinker.cpp | 61 | ||||
-rw-r--r-- | llvm/lib/TargetParser/Triple.cpp | 58 |
2 files changed, 87 insertions, 32 deletions
diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp index 2d8360f..80a4e2a 100644 --- a/llvm/lib/DWARFLinker/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -1026,6 +1026,15 @@ 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; @@ -1637,6 +1646,12 @@ 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, @@ -1720,6 +1735,9 @@ 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, @@ -1727,17 +1745,41 @@ 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; - OutOffset += cloneAttribute(*Die, InputDIE, File, Unit, Val, AttrSpec, - AttrSize, AttrInfo, IsLittleEndian); + 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; } - // Look for accelerator entries. 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; + } + + // Look for accelerator entries. // 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. @@ -1806,8 +1848,19 @@ 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 += getULEB128Size(Die->getAbbrevNumber()); + 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); if (!HasChildren) { // Update our size. diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp index b9fab46..5d4eb79 100644 --- a/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp @@ -90,6 +90,36 @@ 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: @@ -1143,34 +1173,6 @@ 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 |