Commit 709bc112 authored by Alexey Lapshin's avatar Alexey Lapshin
Browse files

[DWARFLinker][NFC] Make interfaces to be compatible.

This patch makes interface of AddressManager from DWARFLinker
to be compatible with AddressesMap from DWARFLinkerParallel.
This makes both linkers to be interchangeable.

Differential Revision: https://reviews.llvm.org/D147455
parent fa43608d
Loading
Loading
Loading
Loading
+17 −11
Original line number Diff line number Diff line
@@ -49,17 +49,23 @@ public:
  /// section.
  virtual bool hasValidRelocs() = 0;

  /// Checks that the specified variable \p DIE references live code section.
  /// Allowed kind of input die: DW_TAG_variable, DW_TAG_constant.
  /// \returns true and sets Info.InDebugMap if it is the case.
  virtual bool isLiveVariable(const DWARFDie &DIE,
                              CompileUnit::DIEInfo &Info) = 0;

  /// Checks that the specified subprogram \p DIE references live code section.
  /// Allowed kind of input die: DW_TAG_subprogram, DW_TAG_label.
  /// \returns true and sets Info.InDebugMap if it is the case.
  virtual bool isLiveSubprogram(const DWARFDie &DIE,
                                CompileUnit::DIEInfo &Info) = 0;
  /// Checks that the specified variable \p DIE references the live code
  /// section and returns the relocation adjustment value (to get the linked
  /// address this value might be added to the source variable address).
  /// Allowed kinds of input DIE: DW_TAG_variable, DW_TAG_constant.
  /// \returns relocation adjustment value or std::nullopt if there is no
  /// corresponding live address.
  virtual std::optional<int64_t>
  getVariableRelocAdjustment(const DWARFDie &DIE) = 0;

  /// Checks that the specified subprogram \p DIE references the live code
  /// section and returns the relocation adjustment value (to get the linked
  /// address this value might be added to the source subprogram address).
  /// Allowed kinds of input DIE: DW_TAG_subprogram, DW_TAG_label.
  /// \returns relocation adjustment value or std::nullopt if there is no
  /// corresponding live address.
  virtual std::optional<int64_t>
  getSubprogramRelocAdjustment(const DWARFDie &DIE) = 0;

  /// Apply the valid relocations to the buffer \p Data, taking into
  /// account that Data is at \p BaseOffset in the .debug_info section.
+16 −4
Original line number Diff line number Diff line
@@ -439,8 +439,15 @@ unsigned DWARFLinker::shouldKeepVariableDIE(AddressesMap &RelocMgr,
  // if the variable has a valid relocation, so that the DIEInfo is filled.
  // However, we don't want a static variable in a function to force us to keep
  // the enclosing function, unless requested explicitly.
  const bool HasLiveMemoryLocation = RelocMgr.isLiveVariable(DIE, MyInfo);
  if (!HasLiveMemoryLocation || ((Flags & TF_InFunctionScope) &&
  std::optional<int64_t> RelocAdjustment =
      RelocMgr.getVariableRelocAdjustment(DIE);

  if (RelocAdjustment) {
    MyInfo.AddrAdjust = *RelocAdjustment;
    MyInfo.InDebugMap = true;
  }

  if (!RelocAdjustment || ((Flags & TF_InFunctionScope) &&
                           !LLVM_UNLIKELY(Options.KeepFunctionForStatic)))
    return Flags;

@@ -468,9 +475,14 @@ unsigned DWARFLinker::shouldKeepSubprogramDIE(
    return Flags;

  assert(LowPc && "low_pc attribute is not an address.");
  if (!RelocMgr.isLiveSubprogram(DIE, MyInfo))
  std::optional<int64_t> RelocAdjustment =
      RelocMgr.getSubprogramRelocAdjustment(DIE);
  if (!RelocAdjustment)
    return Flags;

  MyInfo.AddrAdjust = *RelocAdjustment;
  MyInfo.InDebugMap = true;

  if (Options.Verbose) {
    outs() << "Keeping subprogram DIE:";
    DIDumpOptions DumpOpts;
+23 −22
Original line number Diff line number Diff line
@@ -939,28 +939,28 @@ void DwarfLinkerForBinary::AddressManager::printReloc(const ValidReloc &Reloc) {
                   uint64_t(Mapping.BinaryAddress));
}

void DwarfLinkerForBinary::AddressManager::fillDieInfo(
    const ValidReloc &Reloc, CompileUnit::DIEInfo &Info) {
  Info.AddrAdjust = relocate(Reloc);
int64_t
DwarfLinkerForBinary::AddressManager::getRelocValue(const ValidReloc &Reloc) {
  int64_t AddrAdjust = relocate(Reloc);
  if (Reloc.Mapping->getValue().ObjectAddress)
    Info.AddrAdjust -= uint64_t(*Reloc.Mapping->getValue().ObjectAddress);
  Info.InDebugMap = true;
    AddrAdjust -= uint64_t(*Reloc.Mapping->getValue().ObjectAddress);
  return AddrAdjust;
}

bool DwarfLinkerForBinary::AddressManager::hasValidRelocationAt(
std::optional<int64_t>
DwarfLinkerForBinary::AddressManager::hasValidRelocationAt(
    const std::vector<ValidReloc> &AllRelocs, uint64_t StartOffset,
    uint64_t EndOffset, CompileUnit::DIEInfo &Info) {
    uint64_t EndOffset) {
  std::vector<ValidReloc> Relocs =
      getRelocations(AllRelocs, StartOffset, EndOffset);

  if (Relocs.size() == 0)
    return false;
    return std::nullopt;

  if (Linker.Options.Verbose)
    printReloc(Relocs[0]);
  fillDieInfo(Relocs[0], Info);

  return true;
  return getRelocValue(Relocs[0]);
}

/// Get the starting and ending (exclusive) offset for the
@@ -984,14 +984,15 @@ getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx,
  return std::make_pair(Offset, End);
}

bool DwarfLinkerForBinary::AddressManager::isLiveVariable(
    const DWARFDie &DIE, CompileUnit::DIEInfo &MyInfo) {
std::optional<int64_t>
DwarfLinkerForBinary::AddressManager::getVariableRelocAdjustment(
    const DWARFDie &DIE) {
  const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();

  std::optional<uint32_t> LocationIdx =
      Abbrev->findAttributeIndex(dwarf::DW_AT_location);
  if (!LocationIdx)
    return false;
    return std::nullopt;

  uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
  uint64_t LocationOffset, LocationEndOffset;
@@ -1000,17 +1001,18 @@ bool DwarfLinkerForBinary::AddressManager::isLiveVariable(

  // FIXME: Support relocations debug_addr.
  return hasValidRelocationAt(ValidDebugInfoRelocs, LocationOffset,
                              LocationEndOffset, MyInfo);
                              LocationEndOffset);
}

bool DwarfLinkerForBinary::AddressManager::isLiveSubprogram(
    const DWARFDie &DIE, CompileUnit::DIEInfo &MyInfo) {
std::optional<int64_t>
DwarfLinkerForBinary::AddressManager::getSubprogramRelocAdjustment(
    const DWARFDie &DIE) {
  const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();

  std::optional<uint32_t> LowPcIdx =
      Abbrev->findAttributeIndex(dwarf::DW_AT_low_pc);
  if (!LowPcIdx)
    return false;
    return std::nullopt;

  dwarf::Form Form = Abbrev->getFormByIndex(*LowPcIdx);

@@ -1021,7 +1023,7 @@ bool DwarfLinkerForBinary::AddressManager::isLiveSubprogram(
    std::tie(LowPcOffset, LowPcEndOffset) =
        getAttributeOffsets(Abbrev, *LowPcIdx, Offset, *DIE.getDwarfUnit());
    return hasValidRelocationAt(ValidDebugInfoRelocs, LowPcOffset,
                                LowPcEndOffset, MyInfo);
                                LowPcEndOffset);
  }
  case dwarf::DW_FORM_addrx:
  case dwarf::DW_FORM_addrx1:
@@ -1034,15 +1036,14 @@ bool DwarfLinkerForBinary::AddressManager::isLiveSubprogram(
      uint64_t StartOffset = *AddrOffsetSectionBase + AddrValue->getRawUValue();
      uint64_t EndOffset =
          StartOffset + DIE.getDwarfUnit()->getAddressByteSize();
      return hasValidRelocationAt(ValidDebugAddrRelocs, StartOffset, EndOffset,
                                  MyInfo);
      return hasValidRelocationAt(ValidDebugAddrRelocs, StartOffset, EndOffset);
    }

    Linker.reportWarning("no base offset for address table", SrcFileName);
    return false;
    return std::nullopt;
  }
  default:
    return false;
    return std::nullopt;
  }
}

+11 −11
Original line number Diff line number Diff line
@@ -108,8 +108,8 @@ private:
    /// \returns resolved value.
    uint64_t relocate(const ValidReloc &Reloc) const;

    /// Fill \p Info with address information for the specified \p Reloc.
    void fillDieInfo(const ValidReloc &Reloc, CompileUnit::DIEInfo &Info);
    /// \returns value for the specified \p Reloc.
    int64_t getRelocValue(const ValidReloc &Reloc);

    /// Print contents of debug map entry for the specified \p Reloc.
    void printReloc(const ValidReloc &Reloc);
@@ -172,15 +172,15 @@ private:
    /// Checks that there is a relocation in the \p Relocs array against a
    /// debug map entry between \p StartOffset and \p NextOffset.
    ///
    /// \returns true and sets Info.InDebugMap if it is the case.
    bool hasValidRelocationAt(const std::vector<ValidReloc> &Relocs,
                              uint64_t StartOffset, uint64_t EndOffset,
                              CompileUnit::DIEInfo &Info);

    bool isLiveVariable(const DWARFDie &DIE,
                        CompileUnit::DIEInfo &Info) override;
    bool isLiveSubprogram(const DWARFDie &DIE,
                          CompileUnit::DIEInfo &Info) override;
    /// \returns relocation value if relocation exist, otherwise std::nullopt.
    std::optional<int64_t>
    hasValidRelocationAt(const std::vector<ValidReloc> &Relocs,
                         uint64_t StartOffset, uint64_t EndOffset);

    std::optional<int64_t>
    getVariableRelocAdjustment(const DWARFDie &DIE) override;
    std::optional<int64_t>
    getSubprogramRelocAdjustment(const DWARFDie &DIE) override;

    bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
                          bool IsLittleEndian) override;
+12 −16
Original line number Diff line number Diff line
@@ -70,8 +70,8 @@ public:
  // should be renamed into has valid address ranges
  bool hasValidRelocs() override { return !DWARFAddressRanges.empty(); }

  bool isLiveSubprogram(const DWARFDie &DIE,
                        CompileUnit::DIEInfo &Info) override {
  std::optional<int64_t>
  getSubprogramRelocAdjustment(const DWARFDie &DIE) override {
    assert((DIE.getTag() == dwarf::DW_TAG_subprogram ||
            DIE.getTag() == dwarf::DW_TAG_label) &&
           "Wrong type of input die");
@@ -80,18 +80,16 @@ public:
            dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc))) {
      if (!isDeadAddress(*LowPC, DIE.getDwarfUnit()->getVersion(),
                         Opts.Tombstone,
                         DIE.getDwarfUnit()->getAddressByteSize())) {
        Info.AddrAdjust = 0;
        Info.InDebugMap = true;
        return true;
      }
                         DIE.getDwarfUnit()->getAddressByteSize()))
        // Relocation value for the linked binary is 0.
        return 0;
    }

    return false;
    return std::nullopt;
  }

  bool isLiveVariable(const DWARFDie &DIE,
                      CompileUnit::DIEInfo &Info) override {
  std::optional<int64_t>
  getVariableRelocAdjustment(const DWARFDie &DIE) override {
    assert((DIE.getTag() == dwarf::DW_TAG_variable ||
            DIE.getTag() == dwarf::DW_TAG_constant) &&
           "Wrong type of input die");
@@ -114,11 +112,9 @@ public:
                                     DIE.getDwarfUnit()->getAddressByteSize()));
            });

        if (HasLiveAddresses) {
          Info.AddrAdjust = 0;
          Info.InDebugMap = true;
          return true;
        }
        if (HasLiveAddresses)
          // Relocation value for the linked binary is 0.
          return 0;
      }
    } else {
      // FIXME: missing DW_AT_location is OK here, but other errors should be
@@ -126,7 +122,7 @@ public:
      consumeError(Loc.takeError());
    }

    return false;
    return std::nullopt;
  }

  bool applyValidRelocs(MutableArrayRef<char>, uint64_t, bool) override {