[llvm] abc7f68 - [Dsymutil][Debuginfo][NFC] Refactor dsymutil to separate DWARF optimizing part 2.

Eric Christopher via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 19 13:31:03 PST 2019


Hi Alexey,

I've temporarily reverted this here:

echristo at athyra ~/r/llvm-project> git push
To github.com:llvm/llvm-project.git
   918d3939722..3075cd5c9fc  master -> master

as this caused a layering violation/dependency cycle in the build graph. If
you need any help looking into this let me or Tobias know :)

Thanks and sorry for the inconvenience!

-eric

On Thu, Dec 19, 2019 at 4:42 AM Alexey Lapshin via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

>
> Author: Alexey Lapshin
> Date: 2019-12-19T15:41:48+03:00
> New Revision: abc7f6800df8a1f40e1e2c9ccce826abb0208284
>
> URL:
> https://github.com/llvm/llvm-project/commit/abc7f6800df8a1f40e1e2c9ccce826abb0208284
> DIFF:
> https://github.com/llvm/llvm-project/commit/abc7f6800df8a1f40e1e2c9ccce826abb0208284.diff
>
> LOG: [Dsymutil][Debuginfo][NFC] Refactor dsymutil to separate DWARF
> optimizing part 2.
>
> That patch is extracted from the D70709. It moves CompileUnit, DeclContext
> into llvm/DebugInfo/DWARF. It also adds new file DWARFOptimizer with
> AddressesMap class. AddressesMap generalizes functionality
> from RelocationManager.
>
> Differential Revision: https://reviews.llvm.org/D71271
>
> Added:
>     llvm/include/llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h
>     llvm/include/llvm/DebugInfo/DWARF/DWARFOptDeclContext.h
>     llvm/include/llvm/DebugInfo/DWARF/DWARFOptimizer.h
>     llvm/lib/DebugInfo/DWARF/DWARFOptCompileUnit.cpp
>     llvm/lib/DebugInfo/DWARF/DWARFOptDeclContext.cpp
>     llvm/lib/DebugInfo/DWARF/DWARFOptimizer.cpp
>
> Modified:
>     llvm/lib/DebugInfo/DWARF/CMakeLists.txt
>     llvm/lib/DebugInfo/DWARF/LLVMBuild.txt
>     llvm/tools/dsymutil/CMakeLists.txt
>     llvm/tools/dsymutil/DwarfLinker.cpp
>     llvm/tools/dsymutil/DwarfLinker.h
>     llvm/tools/dsymutil/DwarfStreamer.cpp
>     llvm/tools/dsymutil/DwarfStreamer.h
>
> Removed:
>     llvm/tools/dsymutil/CompileUnit.cpp
>     llvm/tools/dsymutil/CompileUnit.h
>     llvm/tools/dsymutil/DeclContext.cpp
>     llvm/tools/dsymutil/DeclContext.h
>
>
>
> ################################################################################
> diff  --git a/llvm/tools/dsymutil/CompileUnit.h
> b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h
> similarity index 97%
> rename from llvm/tools/dsymutil/CompileUnit.h
> rename to llvm/include/llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h
> index e0f5d3bc65b2..010862966846 100644
> --- a/llvm/tools/dsymutil/CompileUnit.h
> +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h
> @@ -1,4 +1,4 @@
> -//===- tools/dsymutil/CompileUnit.h - Dwarf debug info linker ---*- C++
> -*-===//
> +//===- DWARFOptCompileUnit.h ------------------------------------*- C++
> -*-===//
>  //
>  // Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
>  // See https://llvm.org/LICENSE.txt for license information.
> @@ -6,15 +6,15 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>
> -#ifndef LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H
> -#define LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H
> +#ifndef LLVM_DEBUGINFO_DWARF_OPT_COMPILEUNIT_H
> +#define LLVM_DEBUGINFO_DWARF_OPT_COMPILEUNIT_H
>
>  #include "llvm/ADT/IntervalMap.h"
>  #include "llvm/CodeGen/DIE.h"
>  #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
> +#include "llvm/Support/DataExtractor.h"
>
>  namespace llvm {
> -namespace dsymutil {
>
>  class DeclContext;
>
> @@ -46,7 +46,7 @@ struct PatchLocation {
>  };
>
>  /// Stores all information relating to a compile unit, be it in its
> original
> -/// instance in the object file to its brand new cloned and linked DIE
> tree.
> +/// instance in the object file to its brand new cloned and generated DIE
> tree.
>  class CompileUnit {
>  public:
>    /// Information gathered about a DIE in the object file.
> @@ -325,7 +325,6 @@ class CompileUnit {
>    std::string ClangModuleName;
>  };
>
> -} // end namespace dsymutil
>  } // end namespace llvm
>
> -#endif // LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H
> +#endif // LLVM_DEBUGINFO_DWARF_OPT_COMPILEUNIT_H
>
> diff  --git a/llvm/tools/dsymutil/DeclContext.h
> b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptDeclContext.h
> similarity index 95%
> rename from llvm/tools/dsymutil/DeclContext.h
> rename to llvm/include/llvm/DebugInfo/DWARF/DWARFOptDeclContext.h
> index 36ef50944083..6045ed72b259 100644
> --- a/llvm/tools/dsymutil/DeclContext.h
> +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptDeclContext.h
> @@ -1,4 +1,4 @@
> -//===- tools/dsymutil/DeclContext.h - Dwarf debug info linker ---*- C++
> -*-===//
> +//===- llvm/DebugInfo/DWARF/DWARFOptDeclContext.h ---------------*- C++
> -*-===//
>  //
>  // Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
>  // See https://llvm.org/LICENSE.txt for license information.
> @@ -6,20 +6,19 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>
> -#ifndef LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
> -#define LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
> +#ifndef LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H
> +#define LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H
>
> -#include "CompileUnit.h"
>  #include "llvm/ADT/DenseMap.h"
>  #include "llvm/ADT/DenseMapInfo.h"
>  #include "llvm/ADT/DenseSet.h"
>  #include "llvm/ADT/StringRef.h"
>  #include "llvm/CodeGen/NonRelocatableStringpool.h"
>  #include "llvm/DebugInfo/DWARF/DWARFDie.h"
> +#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"
>  #include "llvm/Support/Path.h"
>
>  namespace llvm {
> -namespace dsymutil {
>
>  struct DeclMapInfo;
>
> @@ -165,7 +164,6 @@ struct DeclMapInfo : private DenseMapInfo<DeclContext
> *> {
>    }
>  };
>
> -} // end namespace dsymutil
>  } // end namespace llvm
>
> -#endif // LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
> +#endif // LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H
>
> diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFOptimizer.h
> b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptimizer.h
> new file mode 100644
> index 000000000000..5700c97a92fe
> --- /dev/null
> +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFOptimizer.h
> @@ -0,0 +1,86 @@
> +//===- llvm/DebugInfo/DWARF/DWARFOptimizer.h --------------------*- C++
> -*-===//
> +//
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
> +// See https://llvm.org/LICENSE.txt for license information.
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_DEBUGINFO_DWARFOPTIMIZER_H
> +#define LLVM_DEBUGINFO_DWARFOPTIMIZER_H
> +
> +#include "llvm/CodeGen/NonRelocatableStringpool.h"
> +#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
> +#include "llvm/DebugInfo/DWARF/DWARFContext.h"
> +#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"
> +#include <map>
> +
> +namespace llvm {
> +
> +enum class DwarfOptimizerClient { Dsymutil, LLD, General };
> +
> +/// Partial address range. Besides an offset, only the
> +/// HighPC is stored. The structure is stored in a map where the LowPC is
> the
> +/// key.
> +struct ObjFileAddressRange {
> +  /// Function HighPC.
> +  uint64_t HighPC;
> +  /// Offset to apply to the linked address.
> +  /// should be 0 for not-linked object file.
> +  int64_t Offset;
> +
> +  ObjFileAddressRange(uint64_t EndPC, int64_t Offset)
> +      : HighPC(EndPC), Offset(Offset) {}
> +
> +  ObjFileAddressRange() : HighPC(0), Offset(0) {}
> +};
> +
> +/// Map LowPC to ObjFileAddressRange.
> +using RangesTy = std::map<uint64_t, ObjFileAddressRange>;
> +
> +/// AddressesMap represents information about valid addresses used
> +/// by debug information. Valid addresses are those which points to
> +/// live code sections. i.e. relocations for these addresses point
> +/// into sections which would be/are placed into resulting binary.
> +class AddressesMap {
> +public:
> +  virtual ~AddressesMap();
> +
> +  /// Returns true if represented addresses are from linked file.
> +  /// Returns false if represented addresses are from not-linked
> +  /// object file.
> +  virtual bool areRelocationsResolved() const = 0;
> +
> +  /// Checks that there are valid relocations against a .debug_info
> +  /// section. Reset current relocation pointer if neccessary.
> +  virtual bool hasValidRelocs(bool resetRelocsPtr = true) = 0;
> +
> +  /// Checks that there is a relocation against .debug_info
> +  /// table between \p StartOffset and \p NextOffset.
> +  ///
> +  /// This function must be called with offsets in strictly ascending
> +  /// order because it never looks back at relocations it already 'went
> past'.
> +  /// \returns true and sets Info.InDebugMap if it is the case.
> +  virtual bool hasValidRelocationAt(uint64_t StartOffset, uint64_t
> EndOffset,
> +                                    CompileUnit::DIEInfo &Info) = 0;
> +
> +  /// Apply the valid relocations to the buffer \p Data, taking into
> +  /// account that Data is at \p BaseOffset in the debug_info section.
> +  ///
> +  /// This function must be called with monotonic \p BaseOffset values.
> +  ///
> +  /// \returns true whether any reloc has been applied.
> +  virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t
> BaseOffset,
> +                                bool IsLittleEndian) = 0;
> +
> +  /// Returns all valid functions address ranges(i.e., those ranges
> +  /// which points to sections with code).
> +  virtual RangesTy &getValidAddressRanges() = 0;
> +
> +  /// Erases all data.
> +  virtual void clear() = 0;
> +};
> +
> +} // end namespace llvm
> +
> +#endif // LLVM_DEBUGINFO_DWARFOPTIMIZER_H
>
> diff  --git a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
> b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
> index 3fe9904f221b..d51fe2653631 100644
> --- a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
> +++ b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
> @@ -27,6 +27,9 @@ add_llvm_component_library(LLVMDebugInfoDWARF
>    DWARFUnitIndex.cpp
>    DWARFUnit.cpp
>    DWARFVerifier.cpp
> +  DWARFOptCompileUnit.cpp
> +  DWARFOptDeclContext.cpp
> +  DWARFOptimizer.cpp
>
>    ADDITIONAL_HEADER_DIRS
>    ${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/DWARF
>
> diff  --git a/llvm/tools/dsymutil/CompileUnit.cpp
> b/llvm/lib/DebugInfo/DWARF/DWARFOptCompileUnit.cpp
> similarity index 96%
> rename from llvm/tools/dsymutil/CompileUnit.cpp
> rename to llvm/lib/DebugInfo/DWARF/DWARFOptCompileUnit.cpp
> index 036c61a6b926..6ca5f1289283 100644
> --- a/llvm/tools/dsymutil/CompileUnit.cpp
> +++ b/llvm/lib/DebugInfo/DWARF/DWARFOptCompileUnit.cpp
> @@ -1,4 +1,4 @@
> -//===- tools/dsymutil/CompileUnit.h - Dwarf compile unit
> ------------------===//
> +//===- llvm/DebugInfo/DWARF/DWARFOptCompileUnit.cpp
> -----------------------===//
>  //
>  // Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
>  // See https://llvm.org/LICENSE.txt for license information.
> @@ -6,11 +6,10 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>
> -#include "CompileUnit.h"
> -#include "DeclContext.h"
> +#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"
> +#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"
>
>  namespace llvm {
> -namespace dsymutil {
>
>  /// Check if the DIE at \p Idx is in the scope of a function.
>  static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
> @@ -142,5 +141,4 @@ void CompileUnit::addTypeAccelerator(const DIE *Die,
>    Pubtypes.emplace_back(Name, Die, QualifiedNameHash,
> ObjcClassImplementation);
>  }
>
> -} // namespace dsymutil
>  } // namespace llvm
>
> diff  --git a/llvm/tools/dsymutil/DeclContext.cpp
> b/llvm/lib/DebugInfo/DWARF/DWARFOptDeclContext.cpp
> similarity index 98%
> rename from llvm/tools/dsymutil/DeclContext.cpp
> rename to llvm/lib/DebugInfo/DWARF/DWARFOptDeclContext.cpp
> index 1c33b672c26b..95cf58444e1a 100644
> --- a/llvm/tools/dsymutil/DeclContext.cpp
> +++ b/llvm/lib/DebugInfo/DWARF/DWARFOptDeclContext.cpp
> @@ -1,4 +1,4 @@
> -//===- tools/dsymutil/DeclContext.cpp - Declaration context
> ---------------===//
> +//===- llvm/DebugInfo/DWARF/DWARFOptDeclContext.cpp
> -----------------------===//
>  //
>  // Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
>  // See https://llvm.org/LICENSE.txt for license information.
> @@ -6,13 +6,12 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>
> -#include "DeclContext.h"
> +#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"
>  #include "llvm/DebugInfo/DWARF/DWARFContext.h"
>  #include "llvm/DebugInfo/DWARF/DWARFDie.h"
>  #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
>
>  namespace llvm {
> -namespace dsymutil {
>
>  /// Set the last DIE/CU a context was seen in and, possibly invalidate the
>  /// context if it is ambiguous.
> @@ -206,5 +205,5 @@ PointerIntPair<DeclContext *, 1>
> DeclContextTree::getChildDeclContext(
>
>    return PointerIntPair<DeclContext *, 1>(*ContextIter);
>  }
> -} // namespace dsymutil
> +
>  } // namespace llvm
>
> diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFOptimizer.cpp
> b/llvm/lib/DebugInfo/DWARF/DWARFOptimizer.cpp
> new file mode 100644
> index 000000000000..535d2a047076
> --- /dev/null
> +++ b/llvm/lib/DebugInfo/DWARF/DWARFOptimizer.cpp
> @@ -0,0 +1,15 @@
> +//=== llvm/DebugInfo/DWARF/DWARFOptimizer.cpp
> -----------------------------===//
> +//
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
> +// See https://llvm.org/LICENSE.txt for license information.
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/DebugInfo/DWARF/DWARFOptimizer.h"
> +
> +namespace llvm {
> +
> +AddressesMap::~AddressesMap() {}
> +
> +} // namespace llvm
>
> diff  --git a/llvm/lib/DebugInfo/DWARF/LLVMBuild.txt
> b/llvm/lib/DebugInfo/DWARF/LLVMBuild.txt
> index 182be10f0b4c..e72360deaf88 100644
> --- a/llvm/lib/DebugInfo/DWARF/LLVMBuild.txt
> +++ b/llvm/lib/DebugInfo/DWARF/LLVMBuild.txt
> @@ -18,4 +18,4 @@
>  type = Library
>  name = DebugInfoDWARF
>  parent = DebugInfo
> -required_libraries = BinaryFormat Object MC Support
> +required_libraries = BinaryFormat Object MC Support CodeGen
>
> diff  --git a/llvm/tools/dsymutil/CMakeLists.txt
> b/llvm/tools/dsymutil/CMakeLists.txt
> index b8466baa6346..e21215b2417d 100644
> --- a/llvm/tools/dsymutil/CMakeLists.txt
> +++ b/llvm/tools/dsymutil/CMakeLists.txt
> @@ -22,9 +22,7 @@ add_llvm_tool(dsymutil
>    dsymutil.cpp
>    BinaryHolder.cpp
>    CFBundle.cpp
> -  CompileUnit.cpp
>    DebugMap.cpp
> -  DeclContext.cpp
>    DwarfLinker.cpp
>    DwarfStreamer.cpp
>    MachODebugMapParser.cpp
>
> diff  --git a/llvm/tools/dsymutil/DwarfLinker.cpp
> b/llvm/tools/dsymutil/DwarfLinker.cpp
> index 64acab698434..521d3635dab2 100644
> --- a/llvm/tools/dsymutil/DwarfLinker.cpp
> +++ b/llvm/tools/dsymutil/DwarfLinker.cpp
> @@ -9,7 +9,6 @@
>  #include "DwarfLinker.h"
>  #include "BinaryHolder.h"
>  #include "DebugMap.h"
> -#include "DeclContext.h"
>  #include "DwarfStreamer.h"
>  #include "MachOUtils.h"
>  #include "dsymutil.h"
> @@ -45,6 +44,7 @@
>  #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
>  #include "llvm/DebugInfo/DWARF/DWARFDie.h"
>  #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
> +#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"
>  #include "llvm/DebugInfo/DWARF/DWARFSection.h"
>  #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
>  #include "llvm/MC/MCAsmBackend.h"
> @@ -374,30 +374,6 @@ static bool dieNeedsChildrenToBeMeaningful(uint32_t
> Tag) {
>  }
>
>  void DwarfLinker::startDebugObject(LinkContext &Context) {
> -  // Iterate over the debug map entries and put all the ones that are
> -  // functions (because they have a size) into the Ranges map. This map is
> -  // very similar to the FunctionRanges that are stored in each unit,
> with 2
> -  // notable
> diff erences:
> -  //
> -  //  1. Obviously this one is global, while the other ones are per-unit.
> -  //
> -  //  2. This one contains not only the functions described in the DIE
> -  //     tree, but also the ones that are only in the debug map.
> -  //
> -  // The latter information is required to reproduce dsymutil's logic
> while
> -  // linking line tables. The cases where this information matters look
> like
> -  // bugs that need to be investigated, but for now we need to reproduce
> -  // dsymutil's behavior.
> -  // FIXME: Once we understood exactly if that information is needed,
> -  // maybe totally remove this (or try to use it to do a real
> -  // -gline-tables-only on Darwin.
> -  for (const auto &Entry : Context.DMO.symbols()) {
> -    const auto &Mapping = Entry.getValue();
> -    if (Mapping.Size && Mapping.ObjectAddress)
> -      Context.Ranges[*Mapping.ObjectAddress] = DebugMapObjectRange(
> -          *Mapping.ObjectAddress + Mapping.Size,
> -          int64_t(Mapping.BinaryAddress) - *Mapping.ObjectAddress);
> -  }
>  }
>
>  void DwarfLinker::endDebugObject(LinkContext &Context) {
> @@ -560,7 +536,7 @@ bool
> DwarfLinker::RelocationManager::findValidRelocsInDebugInfo(
>  /// This function must be called with offsets in strictly ascending
>  /// order because it never looks back at relocations it already 'went
> past'.
>  /// \returns true and sets Info.InDebugMap if it is the case.
> -bool DwarfLinker::RelocationManager::hasValidRelocation(
> +bool DwarfLinker::RelocationManager::hasValidRelocationAt(
>      uint64_t StartOffset, uint64_t EndOffset, CompileUnit::DIEInfo &Info)
> {
>    assert(NextValidReloc == 0 ||
>           StartOffset > ValidRelocs[NextValidReloc - 1].Offset);
> @@ -651,7 +627,8 @@ unsigned
> DwarfLinker::shouldKeepVariableDIE(RelocationManager &RelocMgr,
>    // always check 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.
> -  if (!RelocMgr.hasValidRelocation(LocationOffset, LocationEndOffset,
> MyInfo) ||
> +  if (!RelocMgr.hasValidRelocationAt(LocationOffset, LocationEndOffset,
> +                                     MyInfo) ||
>        (Flags & TF_InFunctionScope))
>      return Flags;
>
> @@ -689,7 +666,7 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
>    auto LowPc = dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc));
>    assert(LowPc.hasValue() && "low_pc attribute is not an address.");
>    if (!LowPc ||
> -      !RelocMgr.hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo))
> +      !RelocMgr.hasValidRelocationAt(LowPcOffset, LowPcEndOffset, MyInfo))
>      return Flags;
>
>    if (Options.Verbose) {
> @@ -724,7 +701,7 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
>    }
>
>    // Replace the debug map range with a more accurate one.
> -  Ranges[*LowPc] = DebugMapObjectRange(*HighPc, MyInfo.AddrAdjust);
> +  Ranges[*LowPc] = ObjFileAddressRange(*HighPc, MyInfo.AddrAdjust);
>    Unit.addFunctionRange(*LowPc, *HighPc, MyInfo.AddrAdjust);
>    return Flags;
>  }
> @@ -1651,7 +1628,8 @@ DIE *DwarfLinker::DIECloner::cloneDIE(
>    Data =
>        DWARFDataExtractor(DIECopy, Data.isLittleEndian(),
> Data.getAddressSize());
>    // Modify the copy with relocated addresses.
> -  if (RelocMgr.applyValidRelocs(DIECopy, Offset, Data.isLittleEndian())) {
> +  if (RelocMgr.areRelocationsResolved() &&
> +      RelocMgr.applyValidRelocs(DIECopy, Offset, Data.isLittleEndian())) {
>      // If we applied relocations, we store the value of high_pc that was
>      // potentially stored in the input DIE. If high_pc is an address
>      // (Dwarf version == 2), then it might have been relocated to a
> @@ -2393,7 +2371,7 @@ Error DwarfLinker::loadClangModule(
>
>    // Setup access to the debug info.
>    auto DwarfContext = DWARFContext::create(*ErrOrObj);
> -  RelocationManager RelocMgr(*this);
> +  RelocationManager RelocMgr(*this, *ErrOrObj, DMO);
>
>    for (const auto &CU : DwarfContext->compile_units()) {
>      updateDwarfVersion(CU->getVersion());
> @@ -2774,8 +2752,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
>      // Look for relocations that correspond to debug map entries.
>
>      if (LLVM_LIKELY(!Options.Update) &&
> -        !LinkContext.RelocMgr.findValidRelocsInDebugInfo(
> -            *LinkContext.ObjectFile, LinkContext.DMO)) {
> +        !LinkContext.RelocMgr->hasValidRelocs()) {
>        if (Options.Verbose)
>          outs() << "No valid relocations found. Skipping.\n";
>
> @@ -2892,7 +2869,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
>        Streamer->copyInvariantDebugSection(*LinkContext.ObjectFile);
>      } else {
>        for (auto &CurrentUnit : LinkContext.CompileUnits)
> -        lookForDIEsToKeep(LinkContext.RelocMgr, LinkContext.Ranges,
> +        lookForDIEsToKeep(*LinkContext.RelocMgr, LinkContext.Ranges,
>                            LinkContext.CompileUnits,
>                            CurrentUnit->getOrigUnit().getUnitDIE(),
>                            LinkContext.DMO, *CurrentUnit, 0);
> @@ -2901,10 +2878,9 @@ bool DwarfLinker::link(const DebugMap &Map) {
>      // The calls to applyValidRelocs inside cloneDIE will walk the reloc
>      // array again (in the same way findValidRelocsInDebugInfo() did). We
>      // need to reset the NextValidReloc index to the beginning.
> -    LinkContext.RelocMgr.resetValidRelocs();
> -    if (LinkContext.RelocMgr.hasValidRelocs() ||
> LLVM_UNLIKELY(Options.Update))
> -      DIECloner(*this, LinkContext.RelocMgr, DIEAlloc,
> LinkContext.CompileUnits,
> -                Options)
> +    if (LinkContext.RelocMgr->hasValidRelocs() ||
> LLVM_UNLIKELY(Options.Update))
> +      DIECloner(*this, *LinkContext.RelocMgr, DIEAlloc,
> +                LinkContext.CompileUnits, Options)
>            .cloneAllCompileUnits(*LinkContext.DwarfContext,
> LinkContext.DMO,
>                                  LinkContext.Ranges, OffsetsStringPool,
>
>  LinkContext.DwarfContext->isLittleEndian());
>
> diff  --git a/llvm/tools/dsymutil/DwarfLinker.h
> b/llvm/tools/dsymutil/DwarfLinker.h
> index b8d8e9d02e32..748377f802b3 100644
> --- a/llvm/tools/dsymutil/DwarfLinker.h
> +++ b/llvm/tools/dsymutil/DwarfLinker.h
> @@ -10,33 +10,17 @@
>  #define LLVM_TOOLS_DSYMUTIL_DWARFLINKER_H
>
>  #include "BinaryHolder.h"
> -#include "CompileUnit.h"
>  #include "DebugMap.h"
> -#include "DeclContext.h"
>  #include "DwarfStreamer.h"
>  #include "LinkUtils.h"
>  #include "llvm/DebugInfo/DWARF/DWARFContext.h"
> +#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"
> +#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"
> +#include "llvm/DebugInfo/DWARF/DWARFOptimizer.h"
>
>  namespace llvm {
>  namespace dsymutil {
>
> -/// Partial address range for debug map objects. Besides an offset, only
> the
> -/// HighPC is stored. The structure is stored in a map where the LowPC is
> the
> -/// key.
> -struct DebugMapObjectRange {
> -  /// Function HighPC.
> -  uint64_t HighPC;
> -  /// Offset to apply to the linked address.
> -  int64_t Offset;
> -
> -  DebugMapObjectRange(uint64_t EndPC, int64_t Offset)
> -      : HighPC(EndPC), Offset(Offset) {}
> -
> -  DebugMapObjectRange() : HighPC(0), Offset(0) {}
> -};
> -
> -/// Map LowPC to DebugMapObjectRange.
> -using RangesTy = std::map<uint64_t, DebugMapObjectRange>;
>  using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
>
>  /// The core of the Dwarf linking logic.
> @@ -89,7 +73,7 @@ class DwarfLinker {
>                                OffsetsStringPool &StringPool);
>
>    /// Keeps track of relocations.
> -  class RelocationManager {
> +  class RelocationManager : public AddressesMap {
>      struct ValidReloc {
>        uint64_t Offset;
>        uint32_t Size;
> @@ -117,13 +101,50 @@ class DwarfLinker {
>      /// cheap lookup during the root DIE selection and during DIE cloning.
>      unsigned NextValidReloc = 0;
>
> +    RangesTy AddressRanges;
> +
>    public:
> -    RelocationManager(DwarfLinker &Linker) : Linker(Linker) {}
> +    RelocationManager(DwarfLinker &Linker, const object::ObjectFile &Obj,
> +                      const DebugMapObject &DMO)
> +        : Linker(Linker) {
> +      findValidRelocsInDebugInfo(Obj, DMO);
> +
> +      // Iterate over the debug map entries and put all the ones that are
> +      // functions (because they have a size) into the Ranges map. This
> map is
> +      // very similar to the FunctionRanges that are stored in each unit,
> with 2
> +      // notable
> diff erences:
> +      //
> +      //  1. Obviously this one is global, while the other ones are
> per-unit.
> +      //
> +      //  2. This one contains not only the functions described in the DIE
> +      //     tree, but also the ones that are only in the debug map.
> +      //
> +      // The latter information is required to reproduce dsymutil's logic
> while
> +      // linking line tables. The cases where this information matters
> look like
> +      // bugs that need to be investigated, but for now we need to
> reproduce
> +      // dsymutil's behavior.
> +      // FIXME: Once we understood exactly if that information is needed,
> +      // maybe totally remove this (or try to use it to do a real
> +      // -gline-tables-only on Darwin.
> +      for (const auto &Entry : DMO.symbols()) {
> +        const auto &Mapping = Entry.getValue();
> +        if (Mapping.Size && Mapping.ObjectAddress)
> +          AddressRanges[*Mapping.ObjectAddress] = ObjFileAddressRange(
> +              *Mapping.ObjectAddress + Mapping.Size,
> +              int64_t(Mapping.BinaryAddress) - *Mapping.ObjectAddress);
> +      }
> +    }
> +    virtual ~RelocationManager () override {
> +        clear();
> +    }
>
> -    bool hasValidRelocs() const { return !ValidRelocs.empty(); }
> +    virtual bool areRelocationsResolved() const override { return true; }
>
> -    /// Reset the NextValidReloc counter.
> -    void resetValidRelocs() { NextValidReloc = 0; }
> +    bool hasValidRelocs(bool resetRelocsPtr = true) override {
> +      if (resetRelocsPtr)
> +        NextValidReloc = 0;
> +      return !ValidRelocs.empty();
> +    }
>
>      /// \defgroup FindValidRelocations Translate debug map into a list
>      /// of relevant relocations
> @@ -141,32 +162,43 @@ class DwarfLinker {
>                                const DebugMapObject &DMO);
>      /// @}
>
> -    bool hasValidRelocation(uint64_t StartOffset, uint64_t EndOffset,
> -                            CompileUnit::DIEInfo &Info);
> +    bool hasValidRelocationAt(uint64_t StartOffset, uint64_t EndOffset,
> +                              CompileUnit::DIEInfo &Info) override;
>
>      bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
> -                          bool IsLittleEndian);
> +                          bool IsLittleEndian) override;
> +
> +    RangesTy &getValidAddressRanges() override { return AddressRanges; }
> +
> +    void clear() override {
> +      AddressRanges.clear();
> +      ValidRelocs.clear();
> +      NextValidReloc = 0;
> +    }
>    };
>
>    /// Keeps track of data associated with one object during linking.
>    struct LinkContext {
> +    DwarfLinker &Linker;
>      DebugMapObject &DMO;
> -    const object::ObjectFile *ObjectFile;
> -    RelocationManager RelocMgr;
> +    const object::ObjectFile *ObjectFile = nullptr;
> +    std::unique_ptr<RelocationManager> RelocMgr;
>      std::unique_ptr<DWARFContext> DwarfContext;
>      RangesTy Ranges;
>      UnitListTy CompileUnits;
>
>      LinkContext(const DebugMap &Map, DwarfLinker &Linker, DebugMapObject
> &DMO)
> -        : DMO(DMO), RelocMgr(Linker) {
> +        : Linker(Linker), DMO(DMO) {
>        // Swift ASTs are not object files.
>        if (DMO.getType() == MachO::N_AST) {
>          ObjectFile = nullptr;
>          return;
>        }
> -      auto ErrOrObj = Linker.loadObject(DMO, Map);
> -      ObjectFile = ErrOrObj ? &*ErrOrObj : nullptr;
> -      DwarfContext = ObjectFile ? DWARFContext::create(*ObjectFile) :
> nullptr;
> +      if (auto ErrOrObj = Linker.loadObject(DMO, Map)) {
> +        ObjectFile = &*ErrOrObj;
> +        DwarfContext = DWARFContext::create(*ObjectFile);
> +        RelocMgr.reset(new RelocationManager(Linker, *ObjectFile, DMO));
> +      }
>      }
>
>      /// Clear part of the context that's no longer needed when we're done
> with
> @@ -175,6 +207,7 @@ class DwarfLinker {
>        DwarfContext.reset(nullptr);
>        CompileUnits.clear();
>        Ranges.clear();
> +      RelocMgr->clear();
>      }
>    };
>
>
> diff  --git a/llvm/tools/dsymutil/DwarfStreamer.cpp
> b/llvm/tools/dsymutil/DwarfStreamer.cpp
> index 8747aee458fd..33dc9fc850b5 100644
> --- a/llvm/tools/dsymutil/DwarfStreamer.cpp
> +++ b/llvm/tools/dsymutil/DwarfStreamer.cpp
> @@ -7,11 +7,11 @@
>
>  //===----------------------------------------------------------------------===//
>
>  #include "DwarfStreamer.h"
> -#include "CompileUnit.h"
>  #include "LinkUtils.h"
>  #include "MachOUtils.h"
>  #include "llvm/ADT/Triple.h"
>  #include "llvm/DebugInfo/DWARF/DWARFContext.h"
> +#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"
>  #include "llvm/MC/MCTargetOptions.h"
>  #include "llvm/MC/MCTargetOptionsCommandFlags.inc"
>  #include "llvm/Support/LEB128.h"
>
> diff  --git a/llvm/tools/dsymutil/DwarfStreamer.h
> b/llvm/tools/dsymutil/DwarfStreamer.h
> index baf215ac1315..85e3d48b7581 100644
> --- a/llvm/tools/dsymutil/DwarfStreamer.h
> +++ b/llvm/tools/dsymutil/DwarfStreamer.h
> @@ -9,7 +9,6 @@
>  #ifndef LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H
>  #define LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H
>
> -#include "CompileUnit.h"
>  #include "DebugMap.h"
>  #include "LinkUtils.h"
>  #include "llvm/CodeGen/AccelTable.h"
> @@ -17,6 +16,7 @@
>  #include "llvm/CodeGen/NonRelocatableStringpool.h"
>  #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
>  #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
> +#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"
>  #include "llvm/MC/MCAsmBackend.h"
>  #include "llvm/MC/MCAsmInfo.h"
>  #include "llvm/MC/MCCodeEmitter.h"
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191219/04f7b21e/attachment.html>


More information about the llvm-commits mailing list