brintos

brintos / llvm-project-archived public Read only

0
0
Text · 66.9 KiB · 8d065bf Raw
1856 lines · cpp
1//=== DWARFLinkerCompileUnit.cpp ------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "DWARFLinkerCompileUnit.h"10#include "AcceleratorRecordsSaver.h"11#include "DIEAttributeCloner.h"12#include "DIEGenerator.h"13#include "DependencyTracker.h"14#include "SyntheticTypeNameBuilder.h"15#include "llvm/DWARFLinker/Utils.h"16#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"17#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"18#include "llvm/Support/FileSystem.h"19#include "llvm/Support/FormatVariadic.h"20#include "llvm/Support/Path.h"21#include <utility>22 23using namespace llvm;24using namespace dwarf_linker;25using namespace dwarf_linker::parallel;26 27CompileUnit::CompileUnit(LinkingGlobalData &GlobalData, unsigned ID,28                         StringRef ClangModuleName, DWARFFile &File,29                         OffsetToUnitTy UnitFromOffset,30                         dwarf::FormParams Format, llvm::endianness Endianess)31    : DwarfUnit(GlobalData, ID, ClangModuleName), File(File),32      getUnitFromOffset(UnitFromOffset), Stage(Stage::CreatedNotLoaded),33      AcceleratorRecords(&GlobalData.getAllocator()) {34  UnitName = File.FileName;35  setOutputFormat(Format, Endianess);36  getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);37}38 39CompileUnit::CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit,40                         unsigned ID, StringRef ClangModuleName,41                         DWARFFile &File, OffsetToUnitTy UnitFromOffset,42                         dwarf::FormParams Format, llvm::endianness Endianess)43    : DwarfUnit(GlobalData, ID, ClangModuleName), File(File),44      OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset),45      Stage(Stage::CreatedNotLoaded),46      AcceleratorRecords(&GlobalData.getAllocator()) {47  setOutputFormat(Format, Endianess);48  getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);49 50  DWARFDie CUDie = OrigUnit.getUnitDIE();51  if (!CUDie)52    return;53 54  if (std::optional<DWARFFormValue> Val = CUDie.find(dwarf::DW_AT_language)) {55    uint16_t LangVal = dwarf::toUnsigned(Val, 0);56    if (isODRLanguage(LangVal))57      Language = LangVal;58  }59 60  if (!GlobalData.getOptions().NoODR && Language.has_value())61    NoODR = false;62 63  if (const char *CUName = CUDie.getName(DINameKind::ShortName))64    UnitName = CUName;65  else66    UnitName = File.FileName;67  SysRoot = dwarf::toStringRef(CUDie.find(dwarf::DW_AT_LLVM_sysroot)).str();68}69 70void CompileUnit::loadLineTable() {71  LineTablePtr = File.Dwarf->getLineTableForUnit(&getOrigUnit());72}73 74void CompileUnit::maybeResetToLoadedStage() {75  // Nothing to reset if stage is less than "Loaded".76  if (getStage() < Stage::Loaded)77    return;78 79  // Note: We need to do erasing for "Loaded" stage because80  // if live analysys failed then we will have "Loaded" stage81  // with marking from "LivenessAnalysisDone" stage partially82  // done. That marking should be cleared.83 84  for (DIEInfo &Info : DieInfoArray)85    Info.unsetFlagsWhichSetDuringLiveAnalysis();86 87  LowPc = std::nullopt;88  HighPc = 0;89  Labels.clear();90  Ranges.clear();91  Dependencies.reset(nullptr);92 93  if (getStage() < Stage::Cloned) {94    setStage(Stage::Loaded);95    return;96  }97 98  AcceleratorRecords.erase();99  AbbreviationsSet.clear();100  Abbreviations.clear();101  OutUnitDIE = nullptr;102  DebugAddrIndexMap.clear();103 104  llvm::fill(OutDieOffsetArray, 0);105  llvm::fill(TypeEntries, nullptr);106  eraseSections();107 108  setStage(Stage::CreatedNotLoaded);109}110 111bool CompileUnit::loadInputDIEs() {112  DWARFDie InputUnitDIE = getUnitDIE(false);113  if (!InputUnitDIE)114    return false;115 116  // load input dies, resize Info structures array.117  DieInfoArray.resize(getOrigUnit().getNumDIEs());118  OutDieOffsetArray.resize(getOrigUnit().getNumDIEs(), 0);119  if (!NoODR)120    TypeEntries.resize(getOrigUnit().getNumDIEs());121  return true;122}123 124void CompileUnit::analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,125                                           bool IsODRUnavailableFunctionScope) {126  CompileUnit::DIEInfo &DieInfo = getDIEInfo(DieEntry);127 128  for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry);129       CurChild && CurChild->getAbbreviationDeclarationPtr();130       CurChild = getSiblingEntry(CurChild)) {131    CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild);132    bool ChildIsODRUnavailableFunctionScope = IsODRUnavailableFunctionScope;133 134    if (DieInfo.getIsInMouduleScope())135      ChildInfo.setIsInMouduleScope();136 137    if (DieInfo.getIsInFunctionScope())138      ChildInfo.setIsInFunctionScope();139 140    if (DieInfo.getIsInAnonNamespaceScope())141      ChildInfo.setIsInAnonNamespaceScope();142 143    switch (CurChild->getTag()) {144    case dwarf::DW_TAG_module:145      ChildInfo.setIsInMouduleScope();146      if (DieEntry->getTag() == dwarf::DW_TAG_compile_unit &&147          dwarf::toString(find(CurChild, dwarf::DW_AT_name), "") !=148              getClangModuleName())149        analyzeImportedModule(CurChild);150      break;151    case dwarf::DW_TAG_subprogram:152      ChildInfo.setIsInFunctionScope();153      if (!ChildIsODRUnavailableFunctionScope &&154          !ChildInfo.getIsInMouduleScope()) {155        if (find(CurChild,156                 {dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification}))157          ChildIsODRUnavailableFunctionScope = true;158      }159      break;160    case dwarf::DW_TAG_namespace: {161      UnitEntryPairTy NamespaceEntry = {this, CurChild};162 163      if (find(CurChild, dwarf::DW_AT_extension))164        NamespaceEntry = NamespaceEntry.getNamespaceOrigin();165 166      if (!NamespaceEntry.CU->find(NamespaceEntry.DieEntry, dwarf::DW_AT_name))167        ChildInfo.setIsInAnonNamespaceScope();168    } break;169    default:170      break;171    }172 173    if (!isClangModule() && !getGlobalData().getOptions().UpdateIndexTablesOnly)174      ChildInfo.setTrackLiveness();175 176    if ((!ChildInfo.getIsInAnonNamespaceScope() &&177         !ChildIsODRUnavailableFunctionScope && !NoODR))178      ChildInfo.setODRAvailable();179 180    if (CurChild->hasChildren())181      analyzeDWARFStructureRec(CurChild, ChildIsODRUnavailableFunctionScope);182  }183}184 185StringEntry *CompileUnit::getFileName(unsigned FileIdx,186                                      StringPool &GlobalStrings) {187  if (LineTablePtr) {188    if (LineTablePtr->hasFileAtIndex(FileIdx)) {189      // Cache the resolved paths based on the index in the line table,190      // because calling realpath is expensive.191      ResolvedPathsMap::const_iterator It = ResolvedFullPaths.find(FileIdx);192      if (It == ResolvedFullPaths.end()) {193        std::string OrigFileName;194        bool FoundFileName = LineTablePtr->getFileNameByIndex(195            FileIdx, getOrigUnit().getCompilationDir(),196            DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,197            OrigFileName);198        (void)FoundFileName;199        assert(FoundFileName && "Must get file name from line table");200 201        // Second level of caching, this time based on the file's parent202        // path.203        StringRef FileName = sys::path::filename(OrigFileName);204        StringRef ParentPath = sys::path::parent_path(OrigFileName);205 206        // If the ParentPath has not yet been resolved, resolve and cache it for207        // future look-ups.208        StringMap<StringEntry *>::iterator ParentIt =209            ResolvedParentPaths.find(ParentPath);210        if (ParentIt == ResolvedParentPaths.end()) {211          SmallString<256> RealPath;212          sys::fs::real_path(ParentPath, RealPath);213          ParentIt =214              ResolvedParentPaths215                  .insert({ParentPath, GlobalStrings.insert(RealPath).first})216                  .first;217        }218 219        // Join the file name again with the resolved path.220        SmallString<256> ResolvedPath(ParentIt->second->first());221        sys::path::append(ResolvedPath, FileName);222 223        It = ResolvedFullPaths224                 .insert(std::make_pair(225                     FileIdx, GlobalStrings.insert(ResolvedPath).first))226                 .first;227      }228 229      return It->second;230    }231  }232 233  return nullptr;234}235 236void CompileUnit::cleanupDataAfterClonning() {237  AbbreviationsSet.clear();238  ResolvedFullPaths.shrink_and_clear();239  ResolvedParentPaths.clear();240  FileNames.shrink_and_clear();241  DieInfoArray = SmallVector<DIEInfo>();242  OutDieOffsetArray = SmallVector<uint64_t>();243  TypeEntries = SmallVector<TypeEntry *>();244  Dependencies.reset(nullptr);245  getOrigUnit().clear();246}247 248/// Collect references to parseable Swift interfaces in imported249/// DW_TAG_module blocks.250void CompileUnit::analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry) {251  if (!Language || Language != dwarf::DW_LANG_Swift)252    return;253 254  if (!GlobalData.getOptions().ParseableSwiftInterfaces)255    return;256 257  StringRef Path =258      dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_include_path));259  if (!Path.ends_with(".swiftinterface"))260    return;261  // Don't track interfaces that are part of the SDK.262  StringRef SysRoot =263      dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_sysroot));264  if (SysRoot.empty())265    SysRoot = getSysRoot();266  if (!SysRoot.empty() && Path.starts_with(SysRoot))267    return;268  // Don't track interfaces that are part of the toolchain.269  // For example: Swift, _Concurrency, ...270  StringRef DeveloperDir = guessDeveloperDir(SysRoot);271  if (!DeveloperDir.empty() && Path.starts_with(DeveloperDir))272    return;273  if (isInToolchainDir(Path))274    return;275  if (std::optional<DWARFFormValue> Val = find(DieEntry, dwarf::DW_AT_name)) {276    Expected<const char *> Name = Val->getAsCString();277    if (!Name) {278      warn(Name.takeError());279      return;280    }281 282    auto &Entry = (*GlobalData.getOptions().ParseableSwiftInterfaces)[*Name];283    // The prepend path is applied later when copying.284    SmallString<128> ResolvedPath;285    if (sys::path::is_relative(Path))286      sys::path::append(287          ResolvedPath,288          dwarf::toString(getUnitDIE().find(dwarf::DW_AT_comp_dir), ""));289    sys::path::append(ResolvedPath, Path);290    if (!Entry.empty() && Entry != ResolvedPath) {291      DWARFDie Die = getDIE(DieEntry);292      warn(Twine("conflicting parseable interfaces for Swift Module ") + *Name +293               ": " + Entry + " and " + Path + ".",294           &Die);295    }296    Entry = std::string(ResolvedPath);297  }298}299 300Error CompileUnit::assignTypeNames(TypePool &TypePoolRef) {301  if (!getUnitDIE().isValid())302    return Error::success();303 304  SyntheticTypeNameBuilder NameBuilder(TypePoolRef);305  return assignTypeNamesRec(getDebugInfoEntry(0), NameBuilder);306}307 308Error CompileUnit::assignTypeNamesRec(const DWARFDebugInfoEntry *DieEntry,309                                      SyntheticTypeNameBuilder &NameBuilder) {310  OrderedChildrenIndexAssigner ChildrenIndexAssigner(*this, DieEntry);311  for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry);312       CurChild && CurChild->getAbbreviationDeclarationPtr();313       CurChild = getSiblingEntry(CurChild)) {314    CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild);315    if (!ChildInfo.needToPlaceInTypeTable())316      continue;317 318    assert(ChildInfo.getODRAvailable());319    if (Error Err = NameBuilder.assignName(320            {this, CurChild},321            ChildrenIndexAssigner.getChildIndex(*this, CurChild)))322      return Err;323 324    if (Error Err = assignTypeNamesRec(CurChild, NameBuilder))325      return Err;326  }327 328  return Error::success();329}330 331void CompileUnit::updateDieRefPatchesWithClonedOffsets() {332  if (std::optional<SectionDescriptor *> DebugInfoSection =333          tryGetSectionDescriptor(DebugSectionKind::DebugInfo)) {334 335    (*DebugInfoSection)336        ->ListDebugDieRefPatch.forEach([&](DebugDieRefPatch &Patch) {337          /// Replace stored DIE indexes with DIE output offsets.338          Patch.RefDieIdxOrClonedOffset =339              Patch.RefCU.getPointer()->getDieOutOffset(340                  Patch.RefDieIdxOrClonedOffset);341        });342 343    (*DebugInfoSection)344        ->ListDebugULEB128DieRefPatch.forEach(345            [&](DebugULEB128DieRefPatch &Patch) {346              /// Replace stored DIE indexes with DIE output offsets.347              Patch.RefDieIdxOrClonedOffset =348                  Patch.RefCU.getPointer()->getDieOutOffset(349                      Patch.RefDieIdxOrClonedOffset);350            });351  }352 353  if (std::optional<SectionDescriptor *> DebugLocSection =354          tryGetSectionDescriptor(DebugSectionKind::DebugLoc)) {355    (*DebugLocSection)356        ->ListDebugULEB128DieRefPatch.forEach(357            [](DebugULEB128DieRefPatch &Patch) {358              /// Replace stored DIE indexes with DIE output offsets.359              Patch.RefDieIdxOrClonedOffset =360                  Patch.RefCU.getPointer()->getDieOutOffset(361                      Patch.RefDieIdxOrClonedOffset);362            });363  }364 365  if (std::optional<SectionDescriptor *> DebugLocListsSection =366          tryGetSectionDescriptor(DebugSectionKind::DebugLocLists)) {367    (*DebugLocListsSection)368        ->ListDebugULEB128DieRefPatch.forEach(369            [](DebugULEB128DieRefPatch &Patch) {370              /// Replace stored DIE indexes with DIE output offsets.371              Patch.RefDieIdxOrClonedOffset =372                  Patch.RefCU.getPointer()->getDieOutOffset(373                      Patch.RefDieIdxOrClonedOffset);374            });375  }376}377 378std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference(379    const DWARFFormValue &RefValue,380    ResolveInterCUReferencesMode CanResolveInterCUReferences) {381  CompileUnit *RefCU;382  uint64_t RefDIEOffset;383  if (std::optional<uint64_t> Offset = RefValue.getAsRelativeReference()) {384    RefCU = this;385    RefDIEOffset = RefValue.getUnit()->getOffset() + *Offset;386  } else if (Offset = RefValue.getAsDebugInfoReference(); Offset) {387    RefCU = getUnitFromOffset(*Offset);388    RefDIEOffset = *Offset;389  } else {390    return std::nullopt;391  }392 393  if (RefCU == this) {394    // Referenced DIE is in current compile unit.395    if (std::optional<uint32_t> RefDieIdx = getDIEIndexForOffset(RefDIEOffset))396      return UnitEntryPairTy{this, getDebugInfoEntry(*RefDieIdx)};397  } else if (RefCU && CanResolveInterCUReferences) {398    // Referenced DIE is in other compile unit.399 400    // Check whether DIEs are loaded for that compile unit.401    enum Stage ReferredCUStage = RefCU->getStage();402    if (ReferredCUStage < Stage::Loaded || ReferredCUStage > Stage::Cloned)403      return UnitEntryPairTy{RefCU, nullptr};404 405    if (std::optional<uint32_t> RefDieIdx =406            RefCU->getDIEIndexForOffset(RefDIEOffset))407      return UnitEntryPairTy{RefCU, RefCU->getDebugInfoEntry(*RefDieIdx)};408  } else {409    return UnitEntryPairTy{RefCU, nullptr};410  }411  return std::nullopt;412}413 414std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference(415    const DWARFDebugInfoEntry *DieEntry, dwarf::Attribute Attr,416    ResolveInterCUReferencesMode CanResolveInterCUReferences) {417  if (std::optional<DWARFFormValue> AttrVal = find(DieEntry, Attr))418    return resolveDIEReference(*AttrVal, CanResolveInterCUReferences);419 420  return std::nullopt;421}422 423void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,424                                   int64_t PcOffset) {425  std::lock_guard<std::mutex> Guard(RangesMutex);426 427  Ranges.insert({FuncLowPc, FuncHighPc}, PcOffset);428  if (LowPc)429    LowPc = std::min(*LowPc, FuncLowPc + PcOffset);430  else431    LowPc = FuncLowPc + PcOffset;432  this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);433}434 435void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {436  std::lock_guard<std::mutex> Guard(LabelsMutex);437  Labels.insert({LabelLowPc, PcOffset});438}439 440Error CompileUnit::cloneAndEmitDebugLocations() {441  if (getGlobalData().getOptions().UpdateIndexTablesOnly)442    return Error::success();443 444  if (getOrigUnit().getVersion() < 5) {445    emitLocations(DebugSectionKind::DebugLoc);446    return Error::success();447  }448 449  emitLocations(DebugSectionKind::DebugLocLists);450  return Error::success();451}452 453void CompileUnit::emitLocations(DebugSectionKind LocationSectionKind) {454  SectionDescriptor &DebugInfoSection =455      getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);456 457  if (!DebugInfoSection.ListDebugLocPatch.empty()) {458    SectionDescriptor &OutLocationSection =459        getOrCreateSectionDescriptor(LocationSectionKind);460    DWARFUnit &OrigUnit = getOrigUnit();461 462    uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection);463 464    DebugInfoSection.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) {465      // Get location expressions vector corresponding to the current466      // attribute from the source DWARF.467      uint64_t InputDebugLocSectionOffset = DebugInfoSection.getIntVal(468          Patch.PatchOffset,469          DebugInfoSection.getFormParams().getDwarfOffsetByteSize());470      Expected<DWARFLocationExpressionsVector> OriginalLocations =471          OrigUnit.findLoclistFromOffset(InputDebugLocSectionOffset);472 473      if (!OriginalLocations) {474        warn(OriginalLocations.takeError());475        return;476      }477 478      LinkedLocationExpressionsVector LinkedLocationExpressions;479      for (DWARFLocationExpression &CurExpression : *OriginalLocations) {480        LinkedLocationExpressionsWithOffsetPatches LinkedExpression;481 482        if (CurExpression.Range) {483          // Relocate address range.484          LinkedExpression.Expression.Range = {485              CurExpression.Range->LowPC + Patch.AddrAdjustmentValue,486              CurExpression.Range->HighPC + Patch.AddrAdjustmentValue};487        }488 489        DataExtractor Data(CurExpression.Expr, OrigUnit.isLittleEndian(),490                           OrigUnit.getAddressByteSize());491 492        DWARFExpression InputExpression(Data, OrigUnit.getAddressByteSize(),493                                        OrigUnit.getFormParams().Format);494        cloneDieAttrExpression(InputExpression,495                               LinkedExpression.Expression.Expr,496                               OutLocationSection, Patch.AddrAdjustmentValue,497                               LinkedExpression.Patches);498 499        LinkedLocationExpressions.push_back({LinkedExpression});500      }501 502      // Emit locations list table fragment corresponding to the CurLocAttr.503      DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset,504                             OutLocationSection.OS.tell());505      emitLocListFragment(LinkedLocationExpressions, OutLocationSection);506    });507 508    if (OffsetAfterUnitLength > 0) {509      assert(OffsetAfterUnitLength -510                 OutLocationSection.getFormParams().getDwarfOffsetByteSize() <511             OffsetAfterUnitLength);512      OutLocationSection.apply(513          OffsetAfterUnitLength -514              OutLocationSection.getFormParams().getDwarfOffsetByteSize(),515          dwarf::DW_FORM_sec_offset,516          OutLocationSection.OS.tell() - OffsetAfterUnitLength);517    }518  }519}520 521/// Emit debug locations(.debug_loc, .debug_loclists) header.522uint64_t CompileUnit::emitLocListHeader(SectionDescriptor &OutLocationSection) {523  if (getOrigUnit().getVersion() < 5)524    return 0;525 526  // unit_length.527  OutLocationSection.emitUnitLength(0xBADDEF);528  uint64_t OffsetAfterUnitLength = OutLocationSection.OS.tell();529 530  // Version.531  OutLocationSection.emitIntVal(5, 2);532 533  // Address size.534  OutLocationSection.emitIntVal(OutLocationSection.getFormParams().AddrSize, 1);535 536  // Seg_size537  OutLocationSection.emitIntVal(0, 1);538 539  // Offset entry count540  OutLocationSection.emitIntVal(0, 4);541 542  return OffsetAfterUnitLength;543}544 545/// Emit debug locations(.debug_loc, .debug_loclists) fragment.546uint64_t CompileUnit::emitLocListFragment(547    const LinkedLocationExpressionsVector &LinkedLocationExpression,548    SectionDescriptor &OutLocationSection) {549  uint64_t OffsetBeforeLocationExpression = 0;550 551  if (getOrigUnit().getVersion() < 5) {552    uint64_t BaseAddress = 0;553    if (std::optional<uint64_t> LowPC = getLowPc())554      BaseAddress = *LowPC;555 556    for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :557         LinkedLocationExpression) {558      if (LocExpression.Expression.Range) {559        OutLocationSection.emitIntVal(560            LocExpression.Expression.Range->LowPC - BaseAddress,561            OutLocationSection.getFormParams().AddrSize);562        OutLocationSection.emitIntVal(563            LocExpression.Expression.Range->HighPC - BaseAddress,564            OutLocationSection.getFormParams().AddrSize);565      }566 567      OutLocationSection.emitIntVal(LocExpression.Expression.Expr.size(), 2);568      OffsetBeforeLocationExpression = OutLocationSection.OS.tell();569      for (uint64_t *OffsetPtr : LocExpression.Patches)570        *OffsetPtr += OffsetBeforeLocationExpression;571 572      OutLocationSection.OS573          << StringRef((const char *)LocExpression.Expression.Expr.data(),574                       LocExpression.Expression.Expr.size());575    }576 577    // Emit the terminator entry.578    OutLocationSection.emitIntVal(0,579                                  OutLocationSection.getFormParams().AddrSize);580    OutLocationSection.emitIntVal(0,581                                  OutLocationSection.getFormParams().AddrSize);582    return OffsetBeforeLocationExpression;583  }584 585  std::optional<uint64_t> BaseAddress;586  for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :587       LinkedLocationExpression) {588    if (LocExpression.Expression.Range) {589      // Check whether base address is set. If it is not set yet590      // then set current base address and emit base address selection entry.591      if (!BaseAddress) {592        BaseAddress = LocExpression.Expression.Range->LowPC;593 594        // Emit base address.595        OutLocationSection.emitIntVal(dwarf::DW_LLE_base_addressx, 1);596        encodeULEB128(DebugAddrIndexMap.getValueIndex(*BaseAddress),597                      OutLocationSection.OS);598      }599 600      // Emit type of entry.601      OutLocationSection.emitIntVal(dwarf::DW_LLE_offset_pair, 1);602 603      // Emit start offset relative to base address.604      encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress,605                    OutLocationSection.OS);606 607      // Emit end offset relative to base address.608      encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress,609                    OutLocationSection.OS);610    } else611      // Emit type of entry.612      OutLocationSection.emitIntVal(dwarf::DW_LLE_default_location, 1);613 614    encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.OS);615    OffsetBeforeLocationExpression = OutLocationSection.OS.tell();616    for (uint64_t *OffsetPtr : LocExpression.Patches)617      *OffsetPtr += OffsetBeforeLocationExpression;618 619    OutLocationSection.OS << StringRef(620        (const char *)LocExpression.Expression.Expr.data(),621        LocExpression.Expression.Expr.size());622  }623 624  // Emit the terminator entry.625  OutLocationSection.emitIntVal(dwarf::DW_LLE_end_of_list, 1);626  return OffsetBeforeLocationExpression;627}628 629Error CompileUnit::emitDebugAddrSection() {630  if (GlobalData.getOptions().UpdateIndexTablesOnly)631    return Error::success();632 633  if (getVersion() < 5)634    return Error::success();635 636  if (DebugAddrIndexMap.empty())637    return Error::success();638 639  SectionDescriptor &OutAddrSection =640      getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr);641 642  // Emit section header.643 644  //   Emit length.645  OutAddrSection.emitUnitLength(0xBADDEF);646  uint64_t OffsetAfterSectionLength = OutAddrSection.OS.tell();647 648  //   Emit version.649  OutAddrSection.emitIntVal(5, 2);650 651  //   Emit address size.652  OutAddrSection.emitIntVal(getFormParams().AddrSize, 1);653 654  //   Emit segment size.655  OutAddrSection.emitIntVal(0, 1);656 657  // Emit addresses.658  for (uint64_t AddrValue : DebugAddrIndexMap.getValues())659    OutAddrSection.emitIntVal(AddrValue, getFormParams().AddrSize);660 661  // Patch section length.662  OutAddrSection.apply(663      OffsetAfterSectionLength -664          OutAddrSection.getFormParams().getDwarfOffsetByteSize(),665      dwarf::DW_FORM_sec_offset,666      OutAddrSection.OS.tell() - OffsetAfterSectionLength);667 668  return Error::success();669}670 671Error CompileUnit::cloneAndEmitRanges() {672  if (getGlobalData().getOptions().UpdateIndexTablesOnly)673    return Error::success();674 675  // Build set of linked address ranges for unit function ranges.676  AddressRanges LinkedFunctionRanges;677  for (const AddressRangeValuePair &Range : getFunctionRanges())678    LinkedFunctionRanges.insert(679        {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});680 681  emitAranges(LinkedFunctionRanges);682 683  if (getOrigUnit().getVersion() < 5) {684    cloneAndEmitRangeList(DebugSectionKind::DebugRange, LinkedFunctionRanges);685    return Error::success();686  }687 688  cloneAndEmitRangeList(DebugSectionKind::DebugRngLists, LinkedFunctionRanges);689  return Error::success();690}691 692void CompileUnit::cloneAndEmitRangeList(DebugSectionKind RngSectionKind,693                                        AddressRanges &LinkedFunctionRanges) {694  SectionDescriptor &DebugInfoSection =695      getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);696  SectionDescriptor &OutRangeSection =697      getOrCreateSectionDescriptor(RngSectionKind);698 699  if (!DebugInfoSection.ListDebugRangePatch.empty()) {700    std::optional<AddressRangeValuePair> CachedRange;701    uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);702 703    DebugRangePatch *CompileUnitRangePtr = nullptr;704    DebugInfoSection.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) {705      if (Patch.IsCompileUnitRanges) {706        CompileUnitRangePtr = &Patch;707      } else {708        // Get ranges from the source DWARF corresponding to the current709        // attribute.710        AddressRanges LinkedRanges;711        uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal(712            Patch.PatchOffset,713            DebugInfoSection.getFormParams().getDwarfOffsetByteSize());714        if (Expected<DWARFAddressRangesVector> InputRanges =715                getOrigUnit().findRnglistFromOffset(716                    InputDebugRangesSectionOffset)) {717          // Apply relocation adjustment.718          for (const auto &Range : *InputRanges) {719            if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))720              CachedRange =721                  getFunctionRanges().getRangeThatContains(Range.LowPC);722 723            // All range entries should lie in the function range.724            if (!CachedRange) {725              warn("inconsistent range data.");726              continue;727            }728 729            // Store range for emiting.730            LinkedRanges.insert({Range.LowPC + CachedRange->Value,731                                 Range.HighPC + CachedRange->Value});732          }733        } else {734          llvm::consumeError(InputRanges.takeError());735          warn("invalid range list ignored.");736        }737 738        // Emit linked ranges.739        DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset,740                               OutRangeSection.OS.tell());741        emitRangeListFragment(LinkedRanges, OutRangeSection);742      }743    });744 745    if (CompileUnitRangePtr != nullptr) {746      // Emit compile unit ranges last to be binary compatible with classic747      // dsymutil.748      DebugInfoSection.apply(CompileUnitRangePtr->PatchOffset,749                             dwarf::DW_FORM_sec_offset,750                             OutRangeSection.OS.tell());751      emitRangeListFragment(LinkedFunctionRanges, OutRangeSection);752    }753 754    if (OffsetAfterUnitLength > 0) {755      assert(OffsetAfterUnitLength -756                 OutRangeSection.getFormParams().getDwarfOffsetByteSize() <757             OffsetAfterUnitLength);758      OutRangeSection.apply(759          OffsetAfterUnitLength -760              OutRangeSection.getFormParams().getDwarfOffsetByteSize(),761          dwarf::DW_FORM_sec_offset,762          OutRangeSection.OS.tell() - OffsetAfterUnitLength);763    }764  }765}766 767uint64_t CompileUnit::emitRangeListHeader(SectionDescriptor &OutRangeSection) {768  if (OutRangeSection.getFormParams().Version < 5)769    return 0;770 771  // unit_length.772  OutRangeSection.emitUnitLength(0xBADDEF);773  uint64_t OffsetAfterUnitLength = OutRangeSection.OS.tell();774 775  // Version.776  OutRangeSection.emitIntVal(5, 2);777 778  // Address size.779  OutRangeSection.emitIntVal(OutRangeSection.getFormParams().AddrSize, 1);780 781  // Seg_size782  OutRangeSection.emitIntVal(0, 1);783 784  // Offset entry count785  OutRangeSection.emitIntVal(0, 4);786 787  return OffsetAfterUnitLength;788}789 790void CompileUnit::emitRangeListFragment(const AddressRanges &LinkedRanges,791                                        SectionDescriptor &OutRangeSection) {792  if (OutRangeSection.getFormParams().Version < 5) {793    // Emit ranges.794    uint64_t BaseAddress = 0;795    if (std::optional<uint64_t> LowPC = getLowPc())796      BaseAddress = *LowPC;797 798    for (const AddressRange &Range : LinkedRanges) {799      OutRangeSection.emitIntVal(Range.start() - BaseAddress,800                                 OutRangeSection.getFormParams().AddrSize);801      OutRangeSection.emitIntVal(Range.end() - BaseAddress,802                                 OutRangeSection.getFormParams().AddrSize);803    }804 805    // Add the terminator entry.806    OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);807    OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);808    return;809  }810 811  std::optional<uint64_t> BaseAddress;812  for (const AddressRange &Range : LinkedRanges) {813    if (!BaseAddress) {814      BaseAddress = Range.start();815 816      // Emit base address.817      OutRangeSection.emitIntVal(dwarf::DW_RLE_base_addressx, 1);818      encodeULEB128(getDebugAddrIndex(*BaseAddress), OutRangeSection.OS);819    }820 821    // Emit type of entry.822    OutRangeSection.emitIntVal(dwarf::DW_RLE_offset_pair, 1);823 824    // Emit start offset relative to base address.825    encodeULEB128(Range.start() - *BaseAddress, OutRangeSection.OS);826 827    // Emit end offset relative to base address.828    encodeULEB128(Range.end() - *BaseAddress, OutRangeSection.OS);829  }830 831  // Emit the terminator entry.832  OutRangeSection.emitIntVal(dwarf::DW_RLE_end_of_list, 1);833}834 835void CompileUnit::emitAranges(AddressRanges &LinkedFunctionRanges) {836  if (LinkedFunctionRanges.empty())837    return;838 839  SectionDescriptor &DebugInfoSection =840      getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);841  SectionDescriptor &OutArangesSection =842      getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges);843 844  // Emit Header.845  unsigned HeaderSize =846      sizeof(int32_t) + // Size of contents (w/o this field847      sizeof(int16_t) + // DWARF ARange version number848      sizeof(int32_t) + // Offset of CU in the .debug_info section849      sizeof(int8_t) +  // Pointer Size (in bytes)850      sizeof(int8_t);   // Segment Size (in bytes)851 852  unsigned TupleSize = OutArangesSection.getFormParams().AddrSize * 2;853  unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize));854 855  OutArangesSection.emitOffset(0xBADDEF); // Aranges length856  uint64_t OffsetAfterArangesLengthField = OutArangesSection.OS.tell();857 858  OutArangesSection.emitIntVal(dwarf::DW_ARANGES_VERSION, 2); // Version number859  OutArangesSection.notePatch(860      DebugOffsetPatch{OutArangesSection.OS.tell(), &DebugInfoSection});861  OutArangesSection.emitOffset(0xBADDEF); // Corresponding unit's offset862  OutArangesSection.emitIntVal(OutArangesSection.getFormParams().AddrSize,863                               1);    // Address size864  OutArangesSection.emitIntVal(0, 1); // Segment size865 866  for (size_t Idx = 0; Idx < Padding; Idx++)867    OutArangesSection.emitIntVal(0, 1); // Padding868 869  // Emit linked ranges.870  for (const AddressRange &Range : LinkedFunctionRanges) {871    OutArangesSection.emitIntVal(Range.start(),872                                 OutArangesSection.getFormParams().AddrSize);873    OutArangesSection.emitIntVal(Range.end() - Range.start(),874                                 OutArangesSection.getFormParams().AddrSize);875  }876 877  // Emit terminator.878  OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);879  OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);880 881  uint64_t OffsetAfterArangesEnd = OutArangesSection.OS.tell();882 883  // Update Aranges lentgh.884  OutArangesSection.apply(885      OffsetAfterArangesLengthField -886          OutArangesSection.getFormParams().getDwarfOffsetByteSize(),887      dwarf::DW_FORM_sec_offset,888      OffsetAfterArangesEnd - OffsetAfterArangesLengthField);889}890 891Error CompileUnit::cloneAndEmitDebugMacro() {892  if (getOutUnitDIE() == nullptr)893    return Error::success();894 895  DWARFUnit &OrigUnit = getOrigUnit();896  DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();897 898  // Check for .debug_macro table.899  if (std::optional<uint64_t> MacroAttr =900          dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macros))) {901    if (const DWARFDebugMacro *Table =902            getContaingFile().Dwarf->getDebugMacro()) {903      emitMacroTableImpl(Table, *MacroAttr, true);904    }905  }906 907  // Check for .debug_macinfo table.908  if (std::optional<uint64_t> MacroAttr =909          dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macro_info))) {910    if (const DWARFDebugMacro *Table =911            getContaingFile().Dwarf->getDebugMacinfo()) {912      emitMacroTableImpl(Table, *MacroAttr, false);913    }914  }915 916  return Error::success();917}918 919void CompileUnit::emitMacroTableImpl(const DWARFDebugMacro *MacroTable,920                                     uint64_t OffsetToMacroTable,921                                     bool hasDWARFv5Header) {922  SectionDescriptor &OutSection =923      hasDWARFv5Header924          ? getOrCreateSectionDescriptor(DebugSectionKind::DebugMacro)925          : getOrCreateSectionDescriptor(DebugSectionKind::DebugMacinfo);926 927  bool DefAttributeIsReported = false;928  bool UndefAttributeIsReported = false;929  bool ImportAttributeIsReported = false;930 931  for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) {932    if (OffsetToMacroTable == List.Offset) {933      // Write DWARFv5 header.934      if (hasDWARFv5Header) {935        // Write header version.936        OutSection.emitIntVal(List.Header.Version, sizeof(List.Header.Version));937 938        uint8_t Flags = List.Header.Flags;939 940        // Check for OPCODE_OPERANDS_TABLE.941        if (Flags &942            DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {943          Flags &=944              ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;945          warn("opcode_operands_table is not supported yet.");946        }947 948        // Check for DEBUG_LINE_OFFSET.949        std::optional<uint64_t> StmtListOffset;950        if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {951          // Get offset to the line table from the cloned compile unit.952          for (auto &V : getOutUnitDIE()->values()) {953            if (V.getAttribute() == dwarf::DW_AT_stmt_list) {954              StmtListOffset = V.getDIEInteger().getValue();955              break;956            }957          }958 959          if (!StmtListOffset) {960            Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;961            warn("couldn`t find line table for macro table.");962          }963        }964 965        // Write flags.966        OutSection.emitIntVal(Flags, sizeof(Flags));967 968        // Write offset to line table.969        if (StmtListOffset) {970          OutSection.notePatch(DebugOffsetPatch{971              OutSection.OS.tell(),972              &getOrCreateSectionDescriptor(DebugSectionKind::DebugLine)});973          // TODO: check that List.Header.getOffsetByteSize() and974          // DebugOffsetPatch agree on size.975          OutSection.emitIntVal(0xBADDEF, List.Header.getOffsetByteSize());976        }977      }978 979      // Write macro entries.980      for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) {981        if (MacroEntry.Type == 0) {982          encodeULEB128(MacroEntry.Type, OutSection.OS);983          continue;984        }985 986        uint8_t MacroType = MacroEntry.Type;987        switch (MacroType) {988        default: {989          bool HasVendorSpecificExtension =990              (!hasDWARFv5Header &&991               MacroType == dwarf::DW_MACINFO_vendor_ext) ||992              (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user &&993                                    MacroType <= dwarf::DW_MACRO_hi_user));994 995          if (HasVendorSpecificExtension) {996            // Write macinfo type.997            OutSection.emitIntVal(MacroType, 1);998 999            // Write vendor extension constant.1000            encodeULEB128(MacroEntry.ExtConstant, OutSection.OS);1001 1002            // Write vendor extension string.1003            OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr);1004          } else1005            warn("unknown macro type. skip.");1006        } break;1007        // debug_macro and debug_macinfo share some common encodings.1008        // DW_MACRO_define     == DW_MACINFO_define1009        // DW_MACRO_undef      == DW_MACINFO_undef1010        // DW_MACRO_start_file == DW_MACINFO_start_file1011        // DW_MACRO_end_file   == DW_MACINFO_end_file1012        // For readibility/uniformity we are using DW_MACRO_*.1013        case dwarf::DW_MACRO_define:1014        case dwarf::DW_MACRO_undef: {1015          // Write macinfo type.1016          OutSection.emitIntVal(MacroType, 1);1017 1018          // Write source line.1019          encodeULEB128(MacroEntry.Line, OutSection.OS);1020 1021          // Write macro string.1022          OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr);1023        } break;1024        case dwarf::DW_MACRO_define_strp:1025        case dwarf::DW_MACRO_undef_strp:1026        case dwarf::DW_MACRO_define_strx:1027        case dwarf::DW_MACRO_undef_strx: {1028          // DW_MACRO_*_strx forms are not supported currently.1029          // Convert to *_strp.1030          switch (MacroType) {1031          case dwarf::DW_MACRO_define_strx: {1032            MacroType = dwarf::DW_MACRO_define_strp;1033            if (!DefAttributeIsReported) {1034              warn("DW_MACRO_define_strx unsupported yet. Convert to "1035                   "DW_MACRO_define_strp.");1036              DefAttributeIsReported = true;1037            }1038          } break;1039          case dwarf::DW_MACRO_undef_strx: {1040            MacroType = dwarf::DW_MACRO_undef_strp;1041            if (!UndefAttributeIsReported) {1042              warn("DW_MACRO_undef_strx unsupported yet. Convert to "1043                   "DW_MACRO_undef_strp.");1044              UndefAttributeIsReported = true;1045            }1046          } break;1047          default:1048            // Nothing to do.1049            break;1050          }1051 1052          // Write macinfo type.1053          OutSection.emitIntVal(MacroType, 1);1054 1055          // Write source line.1056          encodeULEB128(MacroEntry.Line, OutSection.OS);1057 1058          // Write macro string.1059          OutSection.emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr);1060          break;1061        }1062        case dwarf::DW_MACRO_start_file: {1063          // Write macinfo type.1064          OutSection.emitIntVal(MacroType, 1);1065          // Write source line.1066          encodeULEB128(MacroEntry.Line, OutSection.OS);1067          // Write source file id.1068          encodeULEB128(MacroEntry.File, OutSection.OS);1069        } break;1070        case dwarf::DW_MACRO_end_file: {1071          // Write macinfo type.1072          OutSection.emitIntVal(MacroType, 1);1073        } break;1074        case dwarf::DW_MACRO_import:1075        case dwarf::DW_MACRO_import_sup: {1076          if (!ImportAttributeIsReported) {1077            warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported "1078                 "yet. remove.");1079            ImportAttributeIsReported = true;1080          }1081        } break;1082        }1083      }1084 1085      return;1086    }1087  }1088}1089 1090void CompileUnit::cloneDieAttrExpression(1091    const DWARFExpression &InputExpression,1092    SmallVectorImpl<uint8_t> &OutputExpression, SectionDescriptor &Section,1093    std::optional<int64_t> VarAddressAdjustment,1094    OffsetsPtrVector &PatchesOffsets) {1095  using Encoding = DWARFExpression::Operation::Encoding;1096 1097  DWARFUnit &OrigUnit = getOrigUnit();1098  uint8_t OrigAddressByteSize = OrigUnit.getAddressByteSize();1099 1100  uint64_t OpOffset = 0;1101  for (auto &Op : InputExpression) {1102    auto Desc = Op.getDescription();1103    // DW_OP_const_type is variable-length and has 31104    // operands. Thus far we only support 2.1105    if ((Desc.Op.size() == 2 && Desc.Op[0] == Encoding::BaseTypeRef) ||1106        (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&1107         Desc.Op[0] != Encoding::Size1))1108      warn("unsupported DW_OP encoding.");1109 1110    if ((Desc.Op.size() == 1 && Desc.Op[0] == Encoding::BaseTypeRef) ||1111        (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&1112         Desc.Op[0] == Encoding::Size1)) {1113      // This code assumes that the other non-typeref operand fits into 1 byte.1114      assert(OpOffset < Op.getEndOffset());1115      uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1;1116      assert(ULEBsize <= 16);1117 1118      // Copy over the operation.1119      assert(!Op.getSubCode() && "SubOps not yet supported");1120      OutputExpression.push_back(Op.getCode());1121      uint64_t RefOffset;1122      if (Desc.Op.size() == 1) {1123        RefOffset = Op.getRawOperand(0);1124      } else {1125        OutputExpression.push_back(Op.getRawOperand(0));1126        RefOffset = Op.getRawOperand(1);1127      }1128      uint8_t ULEB[16];1129      uint32_t Offset = 0;1130      unsigned RealSize = 0;1131      // Look up the base type. For DW_OP_convert, the operand may be 0 to1132      // instead indicate the generic type. The same holds for1133      // DW_OP_reinterpret, which is currently not supported.1134      if (RefOffset > 0 || Op.getCode() != dwarf::DW_OP_convert) {1135        RefOffset += OrigUnit.getOffset();1136        uint32_t RefDieIdx = 0;1137        if (std::optional<uint32_t> Idx =1138                OrigUnit.getDIEIndexForOffset(RefOffset))1139          RefDieIdx = *Idx;1140 1141        // Use fixed size for ULEB128 data, since we need to update that size1142        // later with the proper offsets. Use 5 for DWARF32, 9 for DWARF64.1143        ULEBsize = getFormParams().getDwarfOffsetByteSize() + 1;1144 1145        RealSize = encodeULEB128(0xBADDEF, ULEB, ULEBsize);1146 1147        Section.notePatchWithOffsetUpdate(1148            DebugULEB128DieRefPatch(OutputExpression.size(), this, this,1149                                    RefDieIdx),1150            PatchesOffsets);1151      } else1152        RealSize = encodeULEB128(Offset, ULEB, ULEBsize);1153 1154      if (RealSize > ULEBsize) {1155        // Emit the generic type as a fallback.1156        RealSize = encodeULEB128(0, ULEB, ULEBsize);1157        warn("base type ref doesn't fit.");1158      }1159      assert(RealSize == ULEBsize && "padding failed");1160      ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);1161      OutputExpression.append(ULEBbytes.begin(), ULEBbytes.end());1162    } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&1163               Op.getCode() == dwarf::DW_OP_addrx) {1164      if (std::optional<object::SectionedAddress> SA =1165              OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) {1166        // DWARFLinker does not use addrx forms since it generates relocated1167        // addresses. Replace DW_OP_addrx with DW_OP_addr here.1168        // Argument of DW_OP_addrx should be relocated here as it is not1169        // processed by applyValidRelocs.1170        OutputExpression.push_back(dwarf::DW_OP_addr);1171        uint64_t LinkedAddress = SA->Address + VarAddressAdjustment.value_or(0);1172        if (getEndianness() != llvm::endianness::native)1173          sys::swapByteOrder(LinkedAddress);1174        ArrayRef<uint8_t> AddressBytes(1175            reinterpret_cast<const uint8_t *>(&LinkedAddress),1176            OrigAddressByteSize);1177        OutputExpression.append(AddressBytes.begin(), AddressBytes.end());1178      } else1179        warn("cann't read DW_OP_addrx operand.");1180    } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&1181               Op.getCode() == dwarf::DW_OP_constx) {1182      if (std::optional<object::SectionedAddress> SA =1183              OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) {1184        // DWARFLinker does not use constx forms since it generates relocated1185        // addresses. Replace DW_OP_constx with DW_OP_const[*]u here.1186        // Argument of DW_OP_constx should be relocated here as it is not1187        // processed by applyValidRelocs.1188        std::optional<uint8_t> OutOperandKind;1189        switch (OrigAddressByteSize) {1190        case 2:1191          OutOperandKind = dwarf::DW_OP_const2u;1192          break;1193        case 4:1194          OutOperandKind = dwarf::DW_OP_const4u;1195          break;1196        case 8:1197          OutOperandKind = dwarf::DW_OP_const8u;1198          break;1199        default:1200          warn(1201              formatv(("unsupported address size: {0}."), OrigAddressByteSize));1202          break;1203        }1204 1205        if (OutOperandKind) {1206          OutputExpression.push_back(*OutOperandKind);1207          uint64_t LinkedAddress =1208              SA->Address + VarAddressAdjustment.value_or(0);1209          if (getEndianness() != llvm::endianness::native)1210            sys::swapByteOrder(LinkedAddress);1211          ArrayRef<uint8_t> AddressBytes(1212              reinterpret_cast<const uint8_t *>(&LinkedAddress),1213              OrigAddressByteSize);1214          OutputExpression.append(AddressBytes.begin(), AddressBytes.end());1215        }1216      } else1217        warn("cann't read DW_OP_constx operand.");1218    } else {1219      // Copy over everything else unmodified.1220      StringRef Bytes =1221          InputExpression.getData().slice(OpOffset, Op.getEndOffset());1222      OutputExpression.append(Bytes.begin(), Bytes.end());1223    }1224    OpOffset = Op.getEndOffset();1225  }1226}1227 1228Error CompileUnit::cloneAndEmit(1229    std::optional<std::reference_wrapper<const Triple>> TargetTriple,1230    TypeUnit *ArtificialTypeUnit) {1231  BumpPtrAllocator Allocator;1232 1233  DWARFDie OrigUnitDIE = getOrigUnit().getUnitDIE();1234  if (!OrigUnitDIE.isValid())1235    return Error::success();1236 1237  TypeEntry *RootEntry = nullptr;1238  if (ArtificialTypeUnit)1239    RootEntry = ArtificialTypeUnit->getTypePool().getRoot();1240 1241  // Clone input DIE entry recursively.1242  std::pair<DIE *, TypeEntry *> OutCUDie = cloneDIE(1243      OrigUnitDIE.getDebugInfoEntry(), RootEntry, getDebugInfoHeaderSize(),1244      std::nullopt, std::nullopt, Allocator, ArtificialTypeUnit);1245  setOutUnitDIE(OutCUDie.first);1246 1247  if (!TargetTriple.has_value() || (OutCUDie.first == nullptr))1248    return Error::success();1249 1250  if (Error Err = cloneAndEmitLineTable((*TargetTriple).get()))1251    return Err;1252 1253  if (Error Err = cloneAndEmitDebugMacro())1254    return Err;1255 1256  getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);1257  if (Error Err = emitDebugInfo((*TargetTriple).get()))1258    return Err;1259 1260  // ASSUMPTION: .debug_info section should already be emitted at this point.1261  // cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section1262  // data.1263 1264  if (Error Err = cloneAndEmitRanges())1265    return Err;1266 1267  if (Error Err = cloneAndEmitDebugLocations())1268    return Err;1269 1270  if (Error Err = emitDebugAddrSection())1271    return Err;1272 1273  // Generate Pub accelerator tables.1274  if (llvm::is_contained(GlobalData.getOptions().AccelTables,1275                         DWARFLinker::AccelTableKind::Pub))1276    emitPubAccelerators();1277 1278  if (Error Err = emitDebugStringOffsetSection())1279    return Err;1280 1281  return emitAbbreviations();1282}1283 1284std::pair<DIE *, TypeEntry *> CompileUnit::cloneDIE(1285    const DWARFDebugInfoEntry *InputDieEntry, TypeEntry *ClonedParentTypeDIE,1286    uint64_t OutOffset, std::optional<int64_t> FuncAddressAdjustment,1287    std::optional<int64_t> VarAddressAdjustment, BumpPtrAllocator &Allocator,1288    TypeUnit *ArtificialTypeUnit) {1289  uint32_t InputDieIdx = getDIEIndex(InputDieEntry);1290  CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx);1291 1292  bool NeedToClonePlainDIE = Info.needToKeepInPlainDwarf();1293  bool NeedToCloneTypeDIE =1294      (InputDieEntry->getTag() != dwarf::DW_TAG_compile_unit) &&1295      Info.needToPlaceInTypeTable();1296  std::pair<DIE *, TypeEntry *> ClonedDIE;1297 1298  DIEGenerator PlainDIEGenerator(Allocator, *this);1299 1300  if (NeedToClonePlainDIE)1301    // Create a cloned DIE which would be placed into the cloned version1302    // of input compile unit.1303    ClonedDIE.first = createPlainDIEandCloneAttributes(1304        InputDieEntry, PlainDIEGenerator, OutOffset, FuncAddressAdjustment,1305        VarAddressAdjustment);1306  if (NeedToCloneTypeDIE) {1307    // Create a cloned DIE which would be placed into the artificial type1308    // unit.1309    assert(ArtificialTypeUnit != nullptr);1310    DIEGenerator TypeDIEGenerator(1311        ArtificialTypeUnit->getTypePool().getThreadLocalAllocator(), *this);1312 1313    ClonedDIE.second = createTypeDIEandCloneAttributes(1314        InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE,1315        ArtificialTypeUnit);1316  }1317  TypeEntry *TypeParentForChild =1318      ClonedDIE.second ? ClonedDIE.second : ClonedParentTypeDIE;1319 1320  bool HasPlainChildrenToClone =1321      (ClonedDIE.first && Info.getKeepPlainChildren());1322 1323  bool HasTypeChildrenToClone =1324      ((ClonedDIE.second ||1325        InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) &&1326       Info.getKeepTypeChildren());1327 1328  // Recursively clone children.1329  if (HasPlainChildrenToClone || HasTypeChildrenToClone) {1330    for (const DWARFDebugInfoEntry *CurChild =1331             getFirstChildEntry(InputDieEntry);1332         CurChild && CurChild->getAbbreviationDeclarationPtr();1333         CurChild = getSiblingEntry(CurChild)) {1334      std::pair<DIE *, TypeEntry *> ClonedChild = cloneDIE(1335          CurChild, TypeParentForChild, OutOffset, FuncAddressAdjustment,1336          VarAddressAdjustment, Allocator, ArtificialTypeUnit);1337 1338      if (ClonedChild.first) {1339        OutOffset =1340            ClonedChild.first->getOffset() + ClonedChild.first->getSize();1341        PlainDIEGenerator.addChild(ClonedChild.first);1342      }1343    }1344    assert(ClonedDIE.first == nullptr ||1345           HasPlainChildrenToClone == ClonedDIE.first->hasChildren());1346 1347    // Account for the end of children marker.1348    if (HasPlainChildrenToClone)1349      OutOffset += sizeof(int8_t);1350  }1351 1352  // Update our size.1353  if (ClonedDIE.first != nullptr)1354    ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset());1355 1356  return ClonedDIE;1357}1358 1359DIE *CompileUnit::createPlainDIEandCloneAttributes(1360    const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &PlainDIEGenerator,1361    uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,1362    std::optional<int64_t> &VarAddressAdjustment) {1363  uint32_t InputDieIdx = getDIEIndex(InputDieEntry);1364  CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx);1365  DIE *ClonedDIE = nullptr;1366  bool HasLocationExpressionAddress = false;1367  if (InputDieEntry->getTag() == dwarf::DW_TAG_subprogram) {1368    // Get relocation adjustment value for the current function.1369    FuncAddressAdjustment =1370        getContaingFile().Addresses->getSubprogramRelocAdjustment(1371            getDIE(InputDieEntry), false);1372  } else if (InputDieEntry->getTag() == dwarf::DW_TAG_label) {1373    // Get relocation adjustment value for the current label.1374    std::optional<uint64_t> lowPC =1375        dwarf::toAddress(find(InputDieEntry, dwarf::DW_AT_low_pc));1376    if (lowPC) {1377      LabelMapTy::iterator It = Labels.find(*lowPC);1378      if (It != Labels.end())1379        FuncAddressAdjustment = It->second;1380    }1381  } else if (InputDieEntry->getTag() == dwarf::DW_TAG_variable) {1382    // Get relocation adjustment value for the current variable.1383    std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =1384        getContaingFile().Addresses->getVariableRelocAdjustment(1385            getDIE(InputDieEntry), false);1386 1387    HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;1388    if (LocExprAddrAndRelocAdjustment.first &&1389        LocExprAddrAndRelocAdjustment.second)1390      VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;1391  }1392 1393  ClonedDIE = PlainDIEGenerator.createDIE(InputDieEntry->getTag(), OutOffset);1394 1395  // Offset to the DIE would be used after output DIE tree is deleted.1396  // Thus we need to remember DIE offset separately.1397  rememberDieOutOffset(InputDieIdx, OutOffset);1398 1399  // Clone Attributes.1400  DIEAttributeCloner AttributesCloner(ClonedDIE, *this, this, InputDieEntry,1401                                      PlainDIEGenerator, FuncAddressAdjustment,1402                                      VarAddressAdjustment,1403                                      HasLocationExpressionAddress);1404  AttributesCloner.clone();1405 1406  // Remember accelerator info.1407  AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this, this);1408  AccelRecordsSaver.save(InputDieEntry, ClonedDIE, AttributesCloner.AttrInfo,1409                         nullptr);1410 1411  OutOffset =1412      AttributesCloner.finalizeAbbreviations(Info.getKeepPlainChildren());1413 1414  return ClonedDIE;1415}1416 1417/// Allocates output DIE for the specified \p TypeDescriptor.1418DIE *CompileUnit::allocateTypeDie(TypeEntryBody *TypeDescriptor,1419                                  DIEGenerator &TypeDIEGenerator,1420                                  dwarf::Tag DieTag, bool IsDeclaration,1421                                  bool IsParentDeclaration) {1422  DIE *DefinitionDie = TypeDescriptor->Die;1423  // Do not allocate any new DIE if definition DIE is already met.1424  if (DefinitionDie)1425    return nullptr;1426 1427  DIE *DeclarationDie = TypeDescriptor->DeclarationDie;1428  bool OldParentIsDeclaration = TypeDescriptor->ParentIsDeclaration;1429 1430  if (IsDeclaration && !DeclarationDie) {1431    // Alocate declaration DIE.1432    DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);1433    if (TypeDescriptor->DeclarationDie.compare_exchange_strong(DeclarationDie,1434                                                               NewDie))1435      return NewDie;1436  } else if (IsDeclaration && !IsParentDeclaration && OldParentIsDeclaration) {1437    // Overwrite existing declaration DIE if it's parent is also an declaration1438    // while parent of current declaration DIE is a definition.1439    if (TypeDescriptor->ParentIsDeclaration.compare_exchange_strong(1440            OldParentIsDeclaration, false)) {1441      DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);1442      TypeDescriptor->DeclarationDie = NewDie;1443      return NewDie;1444    }1445  } else if (!IsDeclaration && IsParentDeclaration && !DeclarationDie) {1446    // Alocate declaration DIE since parent of current DIE is marked as1447    // declaration.1448    DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);1449    if (TypeDescriptor->DeclarationDie.compare_exchange_strong(DeclarationDie,1450                                                               NewDie))1451      return NewDie;1452  } else if (!IsDeclaration && !IsParentDeclaration) {1453    // Allocate definition DIE.1454    DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);1455    if (TypeDescriptor->Die.compare_exchange_strong(DefinitionDie, NewDie)) {1456      TypeDescriptor->ParentIsDeclaration = false;1457      return NewDie;1458    }1459  }1460 1461  return nullptr;1462}1463 1464TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(1465    const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &TypeDIEGenerator,1466    TypeEntry *ClonedParentTypeDIE, TypeUnit *ArtificialTypeUnit) {1467  assert(ArtificialTypeUnit != nullptr);1468  uint32_t InputDieIdx = getDIEIndex(InputDieEntry);1469 1470  TypeEntry *Entry = getDieTypeEntry(InputDieIdx);1471  assert(Entry != nullptr);1472  assert(ClonedParentTypeDIE != nullptr);1473  TypeEntryBody *EntryBody =1474      ArtificialTypeUnit->getTypePool().getOrCreateTypeEntryBody(1475          Entry, ClonedParentTypeDIE);1476  assert(EntryBody);1477 1478  bool IsDeclaration =1479      dwarf::toUnsigned(find(InputDieEntry, dwarf::DW_AT_declaration), 0);1480 1481  bool ParentIsDeclaration = false;1482  if (std::optional<uint32_t> ParentIdx = InputDieEntry->getParentIdx())1483    ParentIsDeclaration =1484        dwarf::toUnsigned(find(*ParentIdx, dwarf::DW_AT_declaration), 0);1485 1486  DIE *OutDIE =1487      allocateTypeDie(EntryBody, TypeDIEGenerator, InputDieEntry->getTag(),1488                      IsDeclaration, ParentIsDeclaration);1489 1490  if (OutDIE != nullptr) {1491    assert(ArtificialTypeUnit != nullptr);1492    ArtificialTypeUnit->getSectionDescriptor(DebugSectionKind::DebugInfo);1493 1494    DIEAttributeCloner AttributesCloner(OutDIE, *this, ArtificialTypeUnit,1495                                        InputDieEntry, TypeDIEGenerator,1496                                        std::nullopt, std::nullopt, false);1497    AttributesCloner.clone();1498 1499    // Remember accelerator info.1500    AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this,1501                                              ArtificialTypeUnit);1502    AccelRecordsSaver.save(InputDieEntry, OutDIE, AttributesCloner.AttrInfo,1503                           Entry);1504 1505    // if AttributesCloner.getOutOffset() == 0 then we need to add1506    // 1 to avoid assertion for zero size. We will subtract it back later.1507    OutDIE->setSize(AttributesCloner.getOutOffset() + 1);1508  }1509 1510  return Entry;1511}1512 1513Error CompileUnit::cloneAndEmitLineTable(const Triple &TargetTriple) {1514  const DWARFDebugLine::LineTable *InputLineTable =1515      getContaingFile().Dwarf->getLineTableForUnit(&getOrigUnit());1516  if (InputLineTable == nullptr) {1517    if (getOrigUnit().getUnitDIE().find(dwarf::DW_AT_stmt_list))1518      warn("cann't load line table.");1519    return Error::success();1520  }1521 1522  DWARFDebugLine::LineTable OutLineTable;1523 1524  // Set Line Table header.1525  OutLineTable.Prologue = InputLineTable->Prologue;1526  OutLineTable.Prologue.FormParams.AddrSize = getFormParams().AddrSize;1527 1528  // Set Line Table Rows.1529  if (getGlobalData().getOptions().UpdateIndexTablesOnly) {1530    OutLineTable.Rows = InputLineTable->Rows;1531    // If all the line table contains is a DW_LNE_end_sequence, clear the line1532    // table rows, it will be inserted again in the DWARFStreamer.1533    if (OutLineTable.Rows.size() == 1 && OutLineTable.Rows[0].EndSequence)1534      OutLineTable.Rows.clear();1535 1536    OutLineTable.Sequences = InputLineTable->Sequences;1537  } else {1538    // This vector is the output line table.1539    std::vector<DWARFDebugLine::Row> NewRows;1540    NewRows.reserve(InputLineTable->Rows.size());1541 1542    // Current sequence of rows being extracted, before being inserted1543    // in NewRows.1544    std::vector<DWARFDebugLine::Row> Seq;1545 1546    const auto &FunctionRanges = getFunctionRanges();1547    std::optional<AddressRangeValuePair> CurrRange;1548 1549    // FIXME: This logic is meant to generate exactly the same output as1550    // Darwin's classic dsymutil. There is a nicer way to implement this1551    // by simply putting all the relocated line info in NewRows and simply1552    // sorting NewRows before passing it to emitLineTableForUnit. This1553    // should be correct as sequences for a function should stay1554    // together in the sorted output. There are a few corner cases that1555    // look suspicious though, and that required to implement the logic1556    // this way. Revisit that once initial validation is finished.1557 1558    // Iterate over the object file line info and extract the sequences1559    // that correspond to linked functions.1560    for (DWARFDebugLine::Row Row : InputLineTable->Rows) {1561      // Check whether we stepped out of the range. The range is1562      // half-open, but consider accept the end address of the range if1563      // it is marked as end_sequence in the input (because in that1564      // case, the relocation offset is accurate and that entry won't1565      // serve as the start of another function).1566      if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) {1567        // We just stepped out of a known range. Insert a end_sequence1568        // corresponding to the end of the range.1569        uint64_t StopAddress =1570            CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;1571        CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address);1572        if (StopAddress != -1ULL && !Seq.empty()) {1573          // Insert end sequence row with the computed end address, but1574          // the same line as the previous one.1575          auto NextLine = Seq.back();1576          NextLine.Address.Address = StopAddress;1577          NextLine.EndSequence = 1;1578          NextLine.PrologueEnd = 0;1579          NextLine.BasicBlock = 0;1580          NextLine.EpilogueBegin = 0;1581          Seq.push_back(NextLine);1582          insertLineSequence(Seq, NewRows);1583        }1584 1585        if (!CurrRange)1586          continue;1587      }1588 1589      // Ignore empty sequences.1590      if (Row.EndSequence && Seq.empty())1591        continue;1592 1593      // Relocate row address and add it to the current sequence.1594      Row.Address.Address += CurrRange->Value;1595      Seq.emplace_back(Row);1596 1597      if (Row.EndSequence)1598        insertLineSequence(Seq, NewRows);1599    }1600 1601    OutLineTable.Rows = std::move(NewRows);1602  }1603 1604  return emitDebugLine(TargetTriple, OutLineTable);1605}1606 1607void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,1608                                     std::vector<DWARFDebugLine::Row> &Rows) {1609  if (Seq.empty())1610    return;1611 1612  if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {1613    llvm::append_range(Rows, Seq);1614    Seq.clear();1615    return;1616  }1617 1618  object::SectionedAddress Front = Seq.front().Address;1619  auto InsertPoint = partition_point(1620      Rows, [=](const DWARFDebugLine::Row &O) { return O.Address < Front; });1621 1622  // FIXME: this only removes the unneeded end_sequence if the1623  // sequences have been inserted in order. Using a global sort like1624  // described in cloneAndEmitLineTable() and delaying the end_sequene1625  // elimination to DebugLineEmitter::emit() we can get rid of all of them.1626  if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&1627      InsertPoint->EndSequence) {1628    *InsertPoint = Seq.front();1629    Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());1630  } else {1631    Rows.insert(InsertPoint, Seq.begin(), Seq.end());1632  }1633 1634  Seq.clear();1635}1636 1637#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)1638LLVM_DUMP_METHOD void CompileUnit::DIEInfo::dump() {1639  llvm::errs() << "{";1640  llvm::errs() << "  Placement: ";1641  switch (getPlacement()) {1642  case NotSet:1643    llvm::errs() << "NotSet";1644    break;1645  case TypeTable:1646    llvm::errs() << "TypeTable";1647    break;1648  case PlainDwarf:1649    llvm::errs() << "PlainDwarf";1650    break;1651  case Both:1652    llvm::errs() << "Both";1653    break;1654  }1655 1656  llvm::errs() << "  Keep: " << getKeep();1657  llvm::errs() << "  KeepPlainChildren: " << getKeepPlainChildren();1658  llvm::errs() << "  KeepTypeChildren: " << getKeepTypeChildren();1659  llvm::errs() << "  IsInMouduleScope: " << getIsInMouduleScope();1660  llvm::errs() << "  IsInFunctionScope: " << getIsInFunctionScope();1661  llvm::errs() << "  IsInAnonNamespaceScope: " << getIsInAnonNamespaceScope();1662  llvm::errs() << "  ODRAvailable: " << getODRAvailable();1663  llvm::errs() << "  TrackLiveness: " << getTrackLiveness();1664  llvm::errs() << "}\n";1665}1666#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)1667 1668std::optional<std::pair<StringRef, StringRef>>1669CompileUnit::getDirAndFilenameFromLineTable(1670    const DWARFFormValue &FileIdxValue) {1671  uint64_t FileIdx;1672  if (std::optional<uint64_t> Val = FileIdxValue.getAsUnsignedConstant())1673    FileIdx = *Val;1674  else if (std::optional<int64_t> Val = FileIdxValue.getAsSignedConstant())1675    FileIdx = *Val;1676  else if (std::optional<uint64_t> Val = FileIdxValue.getAsSectionOffset())1677    FileIdx = *Val;1678  else1679    return std::nullopt;1680 1681  return getDirAndFilenameFromLineTable(FileIdx);1682}1683 1684std::optional<std::pair<StringRef, StringRef>>1685CompileUnit::getDirAndFilenameFromLineTable(uint64_t FileIdx) {1686  FileNamesCache::iterator FileData = FileNames.find(FileIdx);1687  if (FileData != FileNames.end())1688    return std::make_pair(StringRef(FileData->second.first),1689                          StringRef(FileData->second.second));1690 1691  if (const DWARFDebugLine::LineTable *LineTable =1692          getOrigUnit().getContext().getLineTableForUnit(&getOrigUnit())) {1693    if (LineTable->hasFileAtIndex(FileIdx)) {1694 1695      const llvm::DWARFDebugLine::FileNameEntry &Entry =1696          LineTable->Prologue.getFileNameEntry(FileIdx);1697 1698      Expected<const char *> Name = Entry.Name.getAsCString();1699      if (!Name) {1700        warn(Name.takeError());1701        return std::nullopt;1702      }1703 1704      std::string FileName = *Name;1705      if (isPathAbsoluteOnWindowsOrPosix(FileName)) {1706        FileNamesCache::iterator FileData =1707            FileNames1708                .insert(std::make_pair(1709                    FileIdx,1710                    std::make_pair(std::string(""), std::move(FileName))))1711                .first;1712        return std::make_pair(StringRef(FileData->second.first),1713                              StringRef(FileData->second.second));1714      }1715 1716      SmallString<256> FilePath;1717      StringRef IncludeDir;1718      // Be defensive about the contents of Entry.1719      if (getVersion() >= 5) {1720        // DirIdx 0 is the compilation directory, so don't include it for1721        // relative names.1722        if ((Entry.DirIdx != 0) &&1723            Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) {1724          Expected<const char *> DirName =1725              LineTable->Prologue.IncludeDirectories[Entry.DirIdx]1726                  .getAsCString();1727          if (DirName)1728            IncludeDir = *DirName;1729          else {1730            warn(DirName.takeError());1731            return std::nullopt;1732          }1733        }1734      } else {1735        if (0 < Entry.DirIdx &&1736            Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) {1737          Expected<const char *> DirName =1738              LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1]1739                  .getAsCString();1740          if (DirName)1741            IncludeDir = *DirName;1742          else {1743            warn(DirName.takeError());1744            return std::nullopt;1745          }1746        }1747      }1748 1749      StringRef CompDir = getOrigUnit().getCompilationDir();1750 1751      if (!CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir)) {1752        sys::path::append(FilePath, sys::path::Style::native, CompDir);1753      }1754 1755      sys::path::append(FilePath, sys::path::Style::native, IncludeDir);1756 1757      FileNamesCache::iterator FileData =1758          FileNames1759              .insert(1760                  std::make_pair(FileIdx, std::make_pair(std::string(FilePath),1761                                                         std::move(FileName))))1762              .first;1763      return std::make_pair(StringRef(FileData->second.first),1764                            StringRef(FileData->second.second));1765    }1766  }1767 1768  return std::nullopt;1769}1770 1771#define MAX_REFERENCIES_DEPTH 10001772UnitEntryPairTy UnitEntryPairTy::getNamespaceOrigin() {1773  UnitEntryPairTy CUDiePair(*this);1774  std::optional<UnitEntryPairTy> RefDiePair;1775  int refDepth = 0;1776  do {1777    RefDiePair = CUDiePair.CU->resolveDIEReference(1778        CUDiePair.DieEntry, dwarf::DW_AT_extension,1779        ResolveInterCUReferencesMode::Resolve);1780    if (!RefDiePair || !RefDiePair->DieEntry)1781      return CUDiePair;1782 1783    CUDiePair = *RefDiePair;1784  } while (refDepth++ < MAX_REFERENCIES_DEPTH);1785 1786  return CUDiePair;1787}1788 1789std::optional<UnitEntryPairTy> UnitEntryPairTy::getParent() {1790  if (std::optional<uint32_t> ParentIdx = DieEntry->getParentIdx())1791    return UnitEntryPairTy{CU, CU->getDebugInfoEntry(*ParentIdx)};1792 1793  return std::nullopt;1794}1795 1796CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(CompileUnit *U)1797    : Ptr(U) {1798  assert(U != nullptr);1799}1800 1801CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(TypeUnit *U) : Ptr(U) {1802  assert(U != nullptr);1803}1804 1805DwarfUnit *CompileUnit::OutputUnitVariantPtr::operator->() {1806  if (isCompileUnit())1807    return getAsCompileUnit();1808  else1809    return getAsTypeUnit();1810}1811 1812bool CompileUnit::OutputUnitVariantPtr::isCompileUnit() {1813  return isa<CompileUnit *>(Ptr);1814}1815 1816bool CompileUnit::OutputUnitVariantPtr::isTypeUnit() {1817  return isa<TypeUnit *>(Ptr);1818}1819 1820CompileUnit *CompileUnit::OutputUnitVariantPtr::getAsCompileUnit() {1821  return cast<CompileUnit *>(Ptr);1822}1823 1824TypeUnit *CompileUnit::OutputUnitVariantPtr::getAsTypeUnit() {1825  return cast<TypeUnit *>(Ptr);1826}1827 1828bool CompileUnit::resolveDependenciesAndMarkLiveness(1829    bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {1830  if (!Dependencies)1831    Dependencies.reset(new DependencyTracker(*this));1832 1833  return Dependencies->resolveDependenciesAndMarkLiveness(1834      InterCUProcessingStarted, HasNewInterconnectedCUs);1835}1836 1837bool CompileUnit::updateDependenciesCompleteness() {1838  assert(Dependencies.get());1839 1840  return Dependencies->updateDependenciesCompleteness();1841}1842 1843void CompileUnit::verifyDependencies() {1844  assert(Dependencies.get());1845 1846  Dependencies->verifyKeepChain();1847}1848 1849ArrayRef<dwarf::Attribute> dwarf_linker::parallel::getODRAttributes() {1850  static dwarf::Attribute ODRAttributes[] = {1851      dwarf::DW_AT_type, dwarf::DW_AT_specification,1852      dwarf::DW_AT_abstract_origin, dwarf::DW_AT_import};1853 1854  return ODRAttributes;1855}1856