mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-04 09:45:00 +00:00
Temporarily Revert "[Dsymutil][Debuginfo][NFC] Refactor dsymutil to separate DWARF optimizing part 2."
as it causes a layering violation/dependency cycle: llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp -> llvm/DebugInfo/DWARF/DWARFExpression.h llvm/include/llvm/DebugInfo/DWARF/DWARFOptimizer.h -> llvm/CodeGen/NonRelocatableStringpool.h This reverts commit abc7f6800df8a1f40e1e2c9ccce826abb0208284.
This commit is contained in:
parent
44b7f48d64
commit
b77d05f0b5
@ -1,86 +0,0 @@
|
|||||||
//===- 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
|
|
@ -27,9 +27,6 @@ add_llvm_component_library(LLVMDebugInfoDWARF
|
|||||||
DWARFUnitIndex.cpp
|
DWARFUnitIndex.cpp
|
||||||
DWARFUnit.cpp
|
DWARFUnit.cpp
|
||||||
DWARFVerifier.cpp
|
DWARFVerifier.cpp
|
||||||
DWARFOptCompileUnit.cpp
|
|
||||||
DWARFOptDeclContext.cpp
|
|
||||||
DWARFOptimizer.cpp
|
|
||||||
|
|
||||||
ADDITIONAL_HEADER_DIRS
|
ADDITIONAL_HEADER_DIRS
|
||||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/DWARF
|
${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/DWARF
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
//=== 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
|
|
@ -18,4 +18,4 @@
|
|||||||
type = Library
|
type = Library
|
||||||
name = DebugInfoDWARF
|
name = DebugInfoDWARF
|
||||||
parent = DebugInfo
|
parent = DebugInfo
|
||||||
required_libraries = BinaryFormat Object MC Support CodeGen
|
required_libraries = BinaryFormat Object MC Support
|
||||||
|
@ -22,7 +22,9 @@ add_llvm_tool(dsymutil
|
|||||||
dsymutil.cpp
|
dsymutil.cpp
|
||||||
BinaryHolder.cpp
|
BinaryHolder.cpp
|
||||||
CFBundle.cpp
|
CFBundle.cpp
|
||||||
|
CompileUnit.cpp
|
||||||
DebugMap.cpp
|
DebugMap.cpp
|
||||||
|
DeclContext.cpp
|
||||||
DwarfLinker.cpp
|
DwarfLinker.cpp
|
||||||
DwarfStreamer.cpp
|
DwarfStreamer.cpp
|
||||||
MachODebugMapParser.cpp
|
MachODebugMapParser.cpp
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//===- llvm/DebugInfo/DWARF/DWARFOptCompileUnit.cpp -----------------------===//
|
//===- tools/dsymutil/CompileUnit.h - Dwarf compile unit ------------------===//
|
||||||
//
|
//
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
@ -6,10 +6,11 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"
|
#include "CompileUnit.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"
|
#include "DeclContext.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
namespace dsymutil {
|
||||||
|
|
||||||
/// Check if the DIE at \p Idx is in the scope of a function.
|
/// Check if the DIE at \p Idx is in the scope of a function.
|
||||||
static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
|
static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
|
||||||
@ -141,4 +142,5 @@ void CompileUnit::addTypeAccelerator(const DIE *Die,
|
|||||||
Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation);
|
Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace dsymutil
|
||||||
} // namespace llvm
|
} // namespace llvm
|
@ -1,4 +1,4 @@
|
|||||||
//===- DWARFOptCompileUnit.h ------------------------------------*- C++ -*-===//
|
//===- tools/dsymutil/CompileUnit.h - Dwarf debug info linker ---*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
@ -6,15 +6,15 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_DEBUGINFO_DWARF_OPT_COMPILEUNIT_H
|
#ifndef LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H
|
||||||
#define LLVM_DEBUGINFO_DWARF_OPT_COMPILEUNIT_H
|
#define LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H
|
||||||
|
|
||||||
#include "llvm/ADT/IntervalMap.h"
|
#include "llvm/ADT/IntervalMap.h"
|
||||||
#include "llvm/CodeGen/DIE.h"
|
#include "llvm/CodeGen/DIE.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
#include "llvm/Support/DataExtractor.h"
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
namespace dsymutil {
|
||||||
|
|
||||||
class DeclContext;
|
class DeclContext;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ struct PatchLocation {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Stores all information relating to a compile unit, be it in its original
|
/// Stores all information relating to a compile unit, be it in its original
|
||||||
/// instance in the object file to its brand new cloned and generated DIE tree.
|
/// instance in the object file to its brand new cloned and linked DIE tree.
|
||||||
class CompileUnit {
|
class CompileUnit {
|
||||||
public:
|
public:
|
||||||
/// Information gathered about a DIE in the object file.
|
/// Information gathered about a DIE in the object file.
|
||||||
@ -325,6 +325,7 @@ private:
|
|||||||
std::string ClangModuleName;
|
std::string ClangModuleName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // end namespace dsymutil
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
#endif // LLVM_DEBUGINFO_DWARF_OPT_COMPILEUNIT_H
|
#endif // LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H
|
@ -1,4 +1,4 @@
|
|||||||
//===- llvm/DebugInfo/DWARF/DWARFOptDeclContext.cpp -----------------------===//
|
//===- tools/dsymutil/DeclContext.cpp - Declaration context ---------------===//
|
||||||
//
|
//
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
@ -6,12 +6,13 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"
|
#include "DeclContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
namespace dsymutil {
|
||||||
|
|
||||||
/// Set the last DIE/CU a context was seen in and, possibly invalidate the
|
/// Set the last DIE/CU a context was seen in and, possibly invalidate the
|
||||||
/// context if it is ambiguous.
|
/// context if it is ambiguous.
|
||||||
@ -205,5 +206,5 @@ PointerIntPair<DeclContext *, 1> DeclContextTree::getChildDeclContext(
|
|||||||
|
|
||||||
return PointerIntPair<DeclContext *, 1>(*ContextIter);
|
return PointerIntPair<DeclContext *, 1>(*ContextIter);
|
||||||
}
|
}
|
||||||
|
} // namespace dsymutil
|
||||||
} // namespace llvm
|
} // namespace llvm
|
@ -1,4 +1,4 @@
|
|||||||
//===- llvm/DebugInfo/DWARF/DWARFOptDeclContext.h ---------------*- C++ -*-===//
|
//===- tools/dsymutil/DeclContext.h - Dwarf debug info linker ---*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
@ -6,19 +6,20 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H
|
#ifndef LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
|
||||||
#define LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H
|
#define LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
|
||||||
|
|
||||||
|
#include "CompileUnit.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/DenseMapInfo.h"
|
#include "llvm/ADT/DenseMapInfo.h"
|
||||||
#include "llvm/ADT/DenseSet.h"
|
#include "llvm/ADT/DenseSet.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/CodeGen/NonRelocatableStringpool.h"
|
#include "llvm/CodeGen/NonRelocatableStringpool.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"
|
|
||||||
#include "llvm/Support/Path.h"
|
#include "llvm/Support/Path.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
namespace dsymutil {
|
||||||
|
|
||||||
struct DeclMapInfo;
|
struct DeclMapInfo;
|
||||||
|
|
||||||
@ -164,6 +165,7 @@ struct DeclMapInfo : private DenseMapInfo<DeclContext *> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // end namespace dsymutil
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
#endif // LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H
|
#endif // LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
|
@ -9,6 +9,7 @@
|
|||||||
#include "DwarfLinker.h"
|
#include "DwarfLinker.h"
|
||||||
#include "BinaryHolder.h"
|
#include "BinaryHolder.h"
|
||||||
#include "DebugMap.h"
|
#include "DebugMap.h"
|
||||||
|
#include "DeclContext.h"
|
||||||
#include "DwarfStreamer.h"
|
#include "DwarfStreamer.h"
|
||||||
#include "MachOUtils.h"
|
#include "MachOUtils.h"
|
||||||
#include "dsymutil.h"
|
#include "dsymutil.h"
|
||||||
@ -44,7 +45,6 @@
|
|||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
||||||
#include "llvm/MC/MCAsmBackend.h"
|
#include "llvm/MC/MCAsmBackend.h"
|
||||||
@ -374,6 +374,30 @@ static bool dieNeedsChildrenToBeMeaningful(uint32_t Tag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DwarfLinker::startDebugObject(LinkContext &Context) {
|
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 differences:
|
||||||
|
//
|
||||||
|
// 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) {
|
void DwarfLinker::endDebugObject(LinkContext &Context) {
|
||||||
@ -536,7 +560,7 @@ bool DwarfLinker::RelocationManager::findValidRelocsInDebugInfo(
|
|||||||
/// This function must be called with offsets in strictly ascending
|
/// This function must be called with offsets in strictly ascending
|
||||||
/// order because it never looks back at relocations it already 'went past'.
|
/// order because it never looks back at relocations it already 'went past'.
|
||||||
/// \returns true and sets Info.InDebugMap if it is the case.
|
/// \returns true and sets Info.InDebugMap if it is the case.
|
||||||
bool DwarfLinker::RelocationManager::hasValidRelocationAt(
|
bool DwarfLinker::RelocationManager::hasValidRelocation(
|
||||||
uint64_t StartOffset, uint64_t EndOffset, CompileUnit::DIEInfo &Info) {
|
uint64_t StartOffset, uint64_t EndOffset, CompileUnit::DIEInfo &Info) {
|
||||||
assert(NextValidReloc == 0 ||
|
assert(NextValidReloc == 0 ||
|
||||||
StartOffset > ValidRelocs[NextValidReloc - 1].Offset);
|
StartOffset > ValidRelocs[NextValidReloc - 1].Offset);
|
||||||
@ -627,8 +651,7 @@ unsigned DwarfLinker::shouldKeepVariableDIE(RelocationManager &RelocMgr,
|
|||||||
// always check if the variable has a valid relocation, so that the
|
// 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
|
// DIEInfo is filled. However, we don't want a static variable in a
|
||||||
// function to force us to keep the enclosing function.
|
// function to force us to keep the enclosing function.
|
||||||
if (!RelocMgr.hasValidRelocationAt(LocationOffset, LocationEndOffset,
|
if (!RelocMgr.hasValidRelocation(LocationOffset, LocationEndOffset, MyInfo) ||
|
||||||
MyInfo) ||
|
|
||||||
(Flags & TF_InFunctionScope))
|
(Flags & TF_InFunctionScope))
|
||||||
return Flags;
|
return Flags;
|
||||||
|
|
||||||
@ -666,7 +689,7 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
|
|||||||
auto LowPc = dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc));
|
auto LowPc = dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc));
|
||||||
assert(LowPc.hasValue() && "low_pc attribute is not an address.");
|
assert(LowPc.hasValue() && "low_pc attribute is not an address.");
|
||||||
if (!LowPc ||
|
if (!LowPc ||
|
||||||
!RelocMgr.hasValidRelocationAt(LowPcOffset, LowPcEndOffset, MyInfo))
|
!RelocMgr.hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo))
|
||||||
return Flags;
|
return Flags;
|
||||||
|
|
||||||
if (Options.Verbose) {
|
if (Options.Verbose) {
|
||||||
@ -701,7 +724,7 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replace the debug map range with a more accurate one.
|
// Replace the debug map range with a more accurate one.
|
||||||
Ranges[*LowPc] = ObjFileAddressRange(*HighPc, MyInfo.AddrAdjust);
|
Ranges[*LowPc] = DebugMapObjectRange(*HighPc, MyInfo.AddrAdjust);
|
||||||
Unit.addFunctionRange(*LowPc, *HighPc, MyInfo.AddrAdjust);
|
Unit.addFunctionRange(*LowPc, *HighPc, MyInfo.AddrAdjust);
|
||||||
return Flags;
|
return Flags;
|
||||||
}
|
}
|
||||||
@ -1628,8 +1651,7 @@ DIE *DwarfLinker::DIECloner::cloneDIE(
|
|||||||
Data =
|
Data =
|
||||||
DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize());
|
DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize());
|
||||||
// Modify the copy with relocated addresses.
|
// Modify the copy with relocated addresses.
|
||||||
if (RelocMgr.areRelocationsResolved() &&
|
if (RelocMgr.applyValidRelocs(DIECopy, Offset, Data.isLittleEndian())) {
|
||||||
RelocMgr.applyValidRelocs(DIECopy, Offset, Data.isLittleEndian())) {
|
|
||||||
// If we applied relocations, we store the value of high_pc that was
|
// 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
|
// potentially stored in the input DIE. If high_pc is an address
|
||||||
// (Dwarf version == 2), then it might have been relocated to a
|
// (Dwarf version == 2), then it might have been relocated to a
|
||||||
@ -2371,7 +2393,7 @@ Error DwarfLinker::loadClangModule(
|
|||||||
|
|
||||||
// Setup access to the debug info.
|
// Setup access to the debug info.
|
||||||
auto DwarfContext = DWARFContext::create(*ErrOrObj);
|
auto DwarfContext = DWARFContext::create(*ErrOrObj);
|
||||||
RelocationManager RelocMgr(*this, *ErrOrObj, DMO);
|
RelocationManager RelocMgr(*this);
|
||||||
|
|
||||||
for (const auto &CU : DwarfContext->compile_units()) {
|
for (const auto &CU : DwarfContext->compile_units()) {
|
||||||
updateDwarfVersion(CU->getVersion());
|
updateDwarfVersion(CU->getVersion());
|
||||||
@ -2752,7 +2774,8 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
|||||||
// Look for relocations that correspond to debug map entries.
|
// Look for relocations that correspond to debug map entries.
|
||||||
|
|
||||||
if (LLVM_LIKELY(!Options.Update) &&
|
if (LLVM_LIKELY(!Options.Update) &&
|
||||||
!LinkContext.RelocMgr->hasValidRelocs()) {
|
!LinkContext.RelocMgr.findValidRelocsInDebugInfo(
|
||||||
|
*LinkContext.ObjectFile, LinkContext.DMO)) {
|
||||||
if (Options.Verbose)
|
if (Options.Verbose)
|
||||||
outs() << "No valid relocations found. Skipping.\n";
|
outs() << "No valid relocations found. Skipping.\n";
|
||||||
|
|
||||||
@ -2869,7 +2892,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
|||||||
Streamer->copyInvariantDebugSection(*LinkContext.ObjectFile);
|
Streamer->copyInvariantDebugSection(*LinkContext.ObjectFile);
|
||||||
} else {
|
} else {
|
||||||
for (auto &CurrentUnit : LinkContext.CompileUnits)
|
for (auto &CurrentUnit : LinkContext.CompileUnits)
|
||||||
lookForDIEsToKeep(*LinkContext.RelocMgr, LinkContext.Ranges,
|
lookForDIEsToKeep(LinkContext.RelocMgr, LinkContext.Ranges,
|
||||||
LinkContext.CompileUnits,
|
LinkContext.CompileUnits,
|
||||||
CurrentUnit->getOrigUnit().getUnitDIE(),
|
CurrentUnit->getOrigUnit().getUnitDIE(),
|
||||||
LinkContext.DMO, *CurrentUnit, 0);
|
LinkContext.DMO, *CurrentUnit, 0);
|
||||||
@ -2878,9 +2901,10 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
|||||||
// The calls to applyValidRelocs inside cloneDIE will walk the reloc
|
// The calls to applyValidRelocs inside cloneDIE will walk the reloc
|
||||||
// array again (in the same way findValidRelocsInDebugInfo() did). We
|
// array again (in the same way findValidRelocsInDebugInfo() did). We
|
||||||
// need to reset the NextValidReloc index to the beginning.
|
// need to reset the NextValidReloc index to the beginning.
|
||||||
if (LinkContext.RelocMgr->hasValidRelocs() || LLVM_UNLIKELY(Options.Update))
|
LinkContext.RelocMgr.resetValidRelocs();
|
||||||
DIECloner(*this, *LinkContext.RelocMgr, DIEAlloc,
|
if (LinkContext.RelocMgr.hasValidRelocs() || LLVM_UNLIKELY(Options.Update))
|
||||||
LinkContext.CompileUnits, Options)
|
DIECloner(*this, LinkContext.RelocMgr, DIEAlloc, LinkContext.CompileUnits,
|
||||||
|
Options)
|
||||||
.cloneAllCompileUnits(*LinkContext.DwarfContext, LinkContext.DMO,
|
.cloneAllCompileUnits(*LinkContext.DwarfContext, LinkContext.DMO,
|
||||||
LinkContext.Ranges, OffsetsStringPool,
|
LinkContext.Ranges, OffsetsStringPool,
|
||||||
LinkContext.DwarfContext->isLittleEndian());
|
LinkContext.DwarfContext->isLittleEndian());
|
||||||
|
@ -10,17 +10,33 @@
|
|||||||
#define LLVM_TOOLS_DSYMUTIL_DWARFLINKER_H
|
#define LLVM_TOOLS_DSYMUTIL_DWARFLINKER_H
|
||||||
|
|
||||||
#include "BinaryHolder.h"
|
#include "BinaryHolder.h"
|
||||||
|
#include "CompileUnit.h"
|
||||||
#include "DebugMap.h"
|
#include "DebugMap.h"
|
||||||
|
#include "DeclContext.h"
|
||||||
#include "DwarfStreamer.h"
|
#include "DwarfStreamer.h"
|
||||||
#include "LinkUtils.h"
|
#include "LinkUtils.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.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 llvm {
|
||||||
namespace dsymutil {
|
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>>;
|
using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
|
||||||
|
|
||||||
/// The core of the Dwarf linking logic.
|
/// The core of the Dwarf linking logic.
|
||||||
@ -73,7 +89,7 @@ private:
|
|||||||
OffsetsStringPool &StringPool);
|
OffsetsStringPool &StringPool);
|
||||||
|
|
||||||
/// Keeps track of relocations.
|
/// Keeps track of relocations.
|
||||||
class RelocationManager : public AddressesMap {
|
class RelocationManager {
|
||||||
struct ValidReloc {
|
struct ValidReloc {
|
||||||
uint64_t Offset;
|
uint64_t Offset;
|
||||||
uint32_t Size;
|
uint32_t Size;
|
||||||
@ -101,50 +117,13 @@ private:
|
|||||||
/// cheap lookup during the root DIE selection and during DIE cloning.
|
/// cheap lookup during the root DIE selection and during DIE cloning.
|
||||||
unsigned NextValidReloc = 0;
|
unsigned NextValidReloc = 0;
|
||||||
|
|
||||||
RangesTy AddressRanges;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RelocationManager(DwarfLinker &Linker, const object::ObjectFile &Obj,
|
RelocationManager(DwarfLinker &Linker) : Linker(Linker) {}
|
||||||
const DebugMapObject &DMO)
|
|
||||||
: Linker(Linker) {
|
|
||||||
findValidRelocsInDebugInfo(Obj, DMO);
|
|
||||||
|
|
||||||
// Iterate over the debug map entries and put all the ones that are
|
bool hasValidRelocs() const { return !ValidRelocs.empty(); }
|
||||||
// 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 differences:
|
|
||||||
//
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
/// \defgroup FindValidRelocations Translate debug map into a list
|
||||||
/// of relevant relocations
|
/// of relevant relocations
|
||||||
@ -162,43 +141,32 @@ private:
|
|||||||
const DebugMapObject &DMO);
|
const DebugMapObject &DMO);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
bool hasValidRelocationAt(uint64_t StartOffset, uint64_t EndOffset,
|
bool hasValidRelocation(uint64_t StartOffset, uint64_t EndOffset,
|
||||||
CompileUnit::DIEInfo &Info) override;
|
CompileUnit::DIEInfo &Info);
|
||||||
|
|
||||||
bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
|
bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
|
||||||
bool IsLittleEndian) override;
|
bool IsLittleEndian);
|
||||||
|
|
||||||
RangesTy &getValidAddressRanges() override { return AddressRanges; }
|
|
||||||
|
|
||||||
void clear() override {
|
|
||||||
AddressRanges.clear();
|
|
||||||
ValidRelocs.clear();
|
|
||||||
NextValidReloc = 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Keeps track of data associated with one object during linking.
|
/// Keeps track of data associated with one object during linking.
|
||||||
struct LinkContext {
|
struct LinkContext {
|
||||||
DwarfLinker &Linker;
|
|
||||||
DebugMapObject &DMO;
|
DebugMapObject &DMO;
|
||||||
const object::ObjectFile *ObjectFile = nullptr;
|
const object::ObjectFile *ObjectFile;
|
||||||
std::unique_ptr<RelocationManager> RelocMgr;
|
RelocationManager RelocMgr;
|
||||||
std::unique_ptr<DWARFContext> DwarfContext;
|
std::unique_ptr<DWARFContext> DwarfContext;
|
||||||
RangesTy Ranges;
|
RangesTy Ranges;
|
||||||
UnitListTy CompileUnits;
|
UnitListTy CompileUnits;
|
||||||
|
|
||||||
LinkContext(const DebugMap &Map, DwarfLinker &Linker, DebugMapObject &DMO)
|
LinkContext(const DebugMap &Map, DwarfLinker &Linker, DebugMapObject &DMO)
|
||||||
: Linker(Linker), DMO(DMO) {
|
: DMO(DMO), RelocMgr(Linker) {
|
||||||
// Swift ASTs are not object files.
|
// Swift ASTs are not object files.
|
||||||
if (DMO.getType() == MachO::N_AST) {
|
if (DMO.getType() == MachO::N_AST) {
|
||||||
ObjectFile = nullptr;
|
ObjectFile = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (auto ErrOrObj = Linker.loadObject(DMO, Map)) {
|
auto ErrOrObj = Linker.loadObject(DMO, Map);
|
||||||
ObjectFile = &*ErrOrObj;
|
ObjectFile = ErrOrObj ? &*ErrOrObj : nullptr;
|
||||||
DwarfContext = DWARFContext::create(*ObjectFile);
|
DwarfContext = ObjectFile ? DWARFContext::create(*ObjectFile) : nullptr;
|
||||||
RelocMgr.reset(new RelocationManager(Linker, *ObjectFile, DMO));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear part of the context that's no longer needed when we're done with
|
/// Clear part of the context that's no longer needed when we're done with
|
||||||
@ -207,7 +175,6 @@ private:
|
|||||||
DwarfContext.reset(nullptr);
|
DwarfContext.reset(nullptr);
|
||||||
CompileUnits.clear();
|
CompileUnits.clear();
|
||||||
Ranges.clear();
|
Ranges.clear();
|
||||||
RelocMgr->clear();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "DwarfStreamer.h"
|
#include "DwarfStreamer.h"
|
||||||
|
#include "CompileUnit.h"
|
||||||
#include "LinkUtils.h"
|
#include "LinkUtils.h"
|
||||||
#include "MachOUtils.h"
|
#include "MachOUtils.h"
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"
|
|
||||||
#include "llvm/MC/MCTargetOptions.h"
|
#include "llvm/MC/MCTargetOptions.h"
|
||||||
#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
|
#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
|
||||||
#include "llvm/Support/LEB128.h"
|
#include "llvm/Support/LEB128.h"
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#ifndef LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H
|
#ifndef LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H
|
||||||
#define LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H
|
#define LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H
|
||||||
|
|
||||||
|
#include "CompileUnit.h"
|
||||||
#include "DebugMap.h"
|
#include "DebugMap.h"
|
||||||
#include "LinkUtils.h"
|
#include "LinkUtils.h"
|
||||||
#include "llvm/CodeGen/AccelTable.h"
|
#include "llvm/CodeGen/AccelTable.h"
|
||||||
@ -16,7 +17,6 @@
|
|||||||
#include "llvm/CodeGen/NonRelocatableStringpool.h"
|
#include "llvm/CodeGen/NonRelocatableStringpool.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"
|
|
||||||
#include "llvm/MC/MCAsmBackend.h"
|
#include "llvm/MC/MCAsmBackend.h"
|
||||||
#include "llvm/MC/MCAsmInfo.h"
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
#include "llvm/MC/MCCodeEmitter.h"
|
#include "llvm/MC/MCCodeEmitter.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user