mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-03 17:02:03 +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
|
||||
DWARFUnit.cpp
|
||||
DWARFVerifier.cpp
|
||||
DWARFOptCompileUnit.cpp
|
||||
DWARFOptDeclContext.cpp
|
||||
DWARFOptimizer.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${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
|
||||
name = DebugInfoDWARF
|
||||
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
|
||||
BinaryHolder.cpp
|
||||
CFBundle.cpp
|
||||
CompileUnit.cpp
|
||||
DebugMap.cpp
|
||||
DeclContext.cpp
|
||||
DwarfLinker.cpp
|
||||
DwarfStreamer.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.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
@ -6,10 +6,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/DebugInfo/DWARF/DWARFOptCompileUnit.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFOptDeclContext.h"
|
||||
#include "CompileUnit.h"
|
||||
#include "DeclContext.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) {
|
||||
@ -141,4 +142,5 @@ void CompileUnit::addTypeAccelerator(const DIE *Die,
|
||||
Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation);
|
||||
}
|
||||
|
||||
} // namespace dsymutil
|
||||
} // 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.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
@ -6,15 +6,15 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEBUGINFO_DWARF_OPT_COMPILEUNIT_H
|
||||
#define LLVM_DEBUGINFO_DWARF_OPT_COMPILEUNIT_H
|
||||
#ifndef LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H
|
||||
#define LLVM_TOOLS_DSYMUTIL_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 generated DIE tree.
|
||||
/// instance in the object file to its brand new cloned and linked DIE tree.
|
||||
class CompileUnit {
|
||||
public:
|
||||
/// Information gathered about a DIE in the object file.
|
||||
@ -325,6 +325,7 @@ private:
|
||||
std::string ClangModuleName;
|
||||
};
|
||||
|
||||
} // end namespace dsymutil
|
||||
} // 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.
|
||||
// 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/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.
|
||||
@ -205,5 +206,5 @@ PointerIntPair<DeclContext *, 1> DeclContextTree::getChildDeclContext(
|
||||
|
||||
return PointerIntPair<DeclContext *, 1>(*ContextIter);
|
||||
}
|
||||
|
||||
} // namespace dsymutil
|
||||
} // 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.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
@ -6,19 +6,20 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H
|
||||
#define LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H
|
||||
#ifndef LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
|
||||
#define LLVM_TOOLS_DSYMUTIL_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;
|
||||
|
||||
@ -164,6 +165,7 @@ struct DeclMapInfo : private DenseMapInfo<DeclContext *> {
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace dsymutil
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_DWARF_OPT_DECLCONTEXT_H
|
||||
#endif // LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
|
@ -9,6 +9,7 @@
|
||||
#include "DwarfLinker.h"
|
||||
#include "BinaryHolder.h"
|
||||
#include "DebugMap.h"
|
||||
#include "DeclContext.h"
|
||||
#include "DwarfStreamer.h"
|
||||
#include "MachOUtils.h"
|
||||
#include "dsymutil.h"
|
||||
@ -44,7 +45,6 @@
|
||||
#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,6 +374,30 @@ 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 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) {
|
||||
@ -536,7 +560,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::hasValidRelocationAt(
|
||||
bool DwarfLinker::RelocationManager::hasValidRelocation(
|
||||
uint64_t StartOffset, uint64_t EndOffset, CompileUnit::DIEInfo &Info) {
|
||||
assert(NextValidReloc == 0 ||
|
||||
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
|
||||
// DIEInfo is filled. However, we don't want a static variable in a
|
||||
// function to force us to keep the enclosing function.
|
||||
if (!RelocMgr.hasValidRelocationAt(LocationOffset, LocationEndOffset,
|
||||
MyInfo) ||
|
||||
if (!RelocMgr.hasValidRelocation(LocationOffset, LocationEndOffset, MyInfo) ||
|
||||
(Flags & TF_InFunctionScope))
|
||||
return Flags;
|
||||
|
||||
@ -666,7 +689,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.hasValidRelocationAt(LowPcOffset, LowPcEndOffset, MyInfo))
|
||||
!RelocMgr.hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo))
|
||||
return Flags;
|
||||
|
||||
if (Options.Verbose) {
|
||||
@ -701,7 +724,7 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
|
||||
}
|
||||
|
||||
// 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);
|
||||
return Flags;
|
||||
}
|
||||
@ -1628,8 +1651,7 @@ DIE *DwarfLinker::DIECloner::cloneDIE(
|
||||
Data =
|
||||
DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize());
|
||||
// Modify the copy with relocated addresses.
|
||||
if (RelocMgr.areRelocationsResolved() &&
|
||||
RelocMgr.applyValidRelocs(DIECopy, Offset, Data.isLittleEndian())) {
|
||||
if (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
|
||||
@ -2371,7 +2393,7 @@ Error DwarfLinker::loadClangModule(
|
||||
|
||||
// Setup access to the debug info.
|
||||
auto DwarfContext = DWARFContext::create(*ErrOrObj);
|
||||
RelocationManager RelocMgr(*this, *ErrOrObj, DMO);
|
||||
RelocationManager RelocMgr(*this);
|
||||
|
||||
for (const auto &CU : DwarfContext->compile_units()) {
|
||||
updateDwarfVersion(CU->getVersion());
|
||||
@ -2752,7 +2774,8 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||
// Look for relocations that correspond to debug map entries.
|
||||
|
||||
if (LLVM_LIKELY(!Options.Update) &&
|
||||
!LinkContext.RelocMgr->hasValidRelocs()) {
|
||||
!LinkContext.RelocMgr.findValidRelocsInDebugInfo(
|
||||
*LinkContext.ObjectFile, LinkContext.DMO)) {
|
||||
if (Options.Verbose)
|
||||
outs() << "No valid relocations found. Skipping.\n";
|
||||
|
||||
@ -2869,7 +2892,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);
|
||||
@ -2878,9 +2901,10 @@ 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.
|
||||
if (LinkContext.RelocMgr->hasValidRelocs() || LLVM_UNLIKELY(Options.Update))
|
||||
DIECloner(*this, *LinkContext.RelocMgr, DIEAlloc,
|
||||
LinkContext.CompileUnits, Options)
|
||||
LinkContext.RelocMgr.resetValidRelocs();
|
||||
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());
|
||||
|
@ -10,17 +10,33 @@
|
||||
#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.
|
||||
@ -73,7 +89,7 @@ private:
|
||||
OffsetsStringPool &StringPool);
|
||||
|
||||
/// Keeps track of relocations.
|
||||
class RelocationManager : public AddressesMap {
|
||||
class RelocationManager {
|
||||
struct ValidReloc {
|
||||
uint64_t Offset;
|
||||
uint32_t Size;
|
||||
@ -101,50 +117,13 @@ private:
|
||||
/// cheap lookup during the root DIE selection and during DIE cloning.
|
||||
unsigned NextValidReloc = 0;
|
||||
|
||||
RangesTy AddressRanges;
|
||||
|
||||
public:
|
||||
RelocationManager(DwarfLinker &Linker, const object::ObjectFile &Obj,
|
||||
const DebugMapObject &DMO)
|
||||
: Linker(Linker) {
|
||||
findValidRelocsInDebugInfo(Obj, DMO);
|
||||
RelocationManager(DwarfLinker &Linker) : Linker(Linker) {}
|
||||
|
||||
// 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 : 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; }
|
||||
|
||||
bool hasValidRelocs(bool resetRelocsPtr = true) override {
|
||||
if (resetRelocsPtr)
|
||||
NextValidReloc = 0;
|
||||
return !ValidRelocs.empty();
|
||||
}
|
||||
/// Reset the NextValidReloc counter.
|
||||
void resetValidRelocs() { NextValidReloc = 0; }
|
||||
|
||||
/// \defgroup FindValidRelocations Translate debug map into a list
|
||||
/// of relevant relocations
|
||||
@ -162,43 +141,32 @@ private:
|
||||
const DebugMapObject &DMO);
|
||||
/// @}
|
||||
|
||||
bool hasValidRelocationAt(uint64_t StartOffset, uint64_t EndOffset,
|
||||
CompileUnit::DIEInfo &Info) override;
|
||||
bool hasValidRelocation(uint64_t StartOffset, uint64_t EndOffset,
|
||||
CompileUnit::DIEInfo &Info);
|
||||
|
||||
bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
|
||||
bool IsLittleEndian) override;
|
||||
|
||||
RangesTy &getValidAddressRanges() override { return AddressRanges; }
|
||||
|
||||
void clear() override {
|
||||
AddressRanges.clear();
|
||||
ValidRelocs.clear();
|
||||
NextValidReloc = 0;
|
||||
}
|
||||
bool IsLittleEndian);
|
||||
};
|
||||
|
||||
/// Keeps track of data associated with one object during linking.
|
||||
struct LinkContext {
|
||||
DwarfLinker &Linker;
|
||||
DebugMapObject &DMO;
|
||||
const object::ObjectFile *ObjectFile = nullptr;
|
||||
std::unique_ptr<RelocationManager> RelocMgr;
|
||||
const object::ObjectFile *ObjectFile;
|
||||
RelocationManager RelocMgr;
|
||||
std::unique_ptr<DWARFContext> DwarfContext;
|
||||
RangesTy Ranges;
|
||||
UnitListTy CompileUnits;
|
||||
|
||||
LinkContext(const DebugMap &Map, DwarfLinker &Linker, DebugMapObject &DMO)
|
||||
: Linker(Linker), DMO(DMO) {
|
||||
: DMO(DMO), RelocMgr(Linker) {
|
||||
// Swift ASTs are not object files.
|
||||
if (DMO.getType() == MachO::N_AST) {
|
||||
ObjectFile = nullptr;
|
||||
return;
|
||||
}
|
||||
if (auto ErrOrObj = Linker.loadObject(DMO, Map)) {
|
||||
ObjectFile = &*ErrOrObj;
|
||||
DwarfContext = DWARFContext::create(*ObjectFile);
|
||||
RelocMgr.reset(new RelocationManager(Linker, *ObjectFile, DMO));
|
||||
}
|
||||
auto ErrOrObj = Linker.loadObject(DMO, Map);
|
||||
ObjectFile = ErrOrObj ? &*ErrOrObj : nullptr;
|
||||
DwarfContext = ObjectFile ? DWARFContext::create(*ObjectFile) : nullptr;
|
||||
}
|
||||
|
||||
/// Clear part of the context that's no longer needed when we're done with
|
||||
@ -207,7 +175,6 @@ private:
|
||||
DwarfContext.reset(nullptr);
|
||||
CompileUnits.clear();
|
||||
Ranges.clear();
|
||||
RelocMgr->clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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"
|
||||
|
@ -9,6 +9,7 @@
|
||||
#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"
|
||||
@ -16,7 +17,6 @@
|
||||
#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"
|
||||
|
Loading…
Reference in New Issue
Block a user