mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[Dsymutil][Debuginfo][NFC] Reland: Refactor dsymutil to separate DWARF optimizing part. #2.
Summary: This patch relands D71271. The problem with D71271 is that it has cyclic dependency: CodeGen->AsmPrinter->DebugInfoDWARF->CodeGen. To avoid cyclic dependency this patch puts implementation for DWARFOptimizer into separate library: lib/DWARFLinker. Thus the difference between this patch and D71271 is in that DWARFOptimizer renamed into DWARFLinker and it`s files are put into lib/DWARFLinker. Reviewers: JDevlieghere, friss, dblaikie, aprantl Reviewed By: JDevlieghere Subscribers: thegameg, merge_guards_bot, probinson, mgorny, hiraditya, llvm-commits Tags: #llvm, #debug-info Differential Revision: https://reviews.llvm.org/D71839
This commit is contained in:
parent
dbbd596280
commit
076ea9fc78
@ -1,4 +1,4 @@
|
|||||||
//===- llvm/CodeGen/NonRelocatableStringpool.h - A simple stringpool -----===//
|
//===- NonRelocatableStringpool.h -------------------------------*- 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.
|
||||||
|
86
include/llvm/DWARFLinker/DWARFLinker.h
Normal file
86
include/llvm/DWARFLinker/DWARFLinker.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
//===- DWARFLinker.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_DWARFLINKER_DWARFLINKER_H
|
||||||
|
#define LLVM_DWARFLINKER_DWARFLINKER_H
|
||||||
|
|
||||||
|
#include "llvm/CodeGen/NonRelocatableStringpool.h"
|
||||||
|
#include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
enum class DwarfLinkerClient { 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_DWARFLINKER_DWARFLINKER_H
|
@ -1,4 +1,4 @@
|
|||||||
//===- tools/dsymutil/CompileUnit.h - Dwarf debug info linker ---*- C++ -*-===//
|
//===- DWARFLinkerCompileUnit.h ---------------------------------*- 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_TOOLS_DSYMUTIL_COMPILEUNIT_H
|
#ifndef LLVM_DWARFLINKER_DWARFLINKERCOMPILEUNIT_H
|
||||||
#define LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H
|
#define LLVM_DWARFLINKER_DWARFLINKERCOMPILEUNIT_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 linked DIE tree.
|
/// instance in the object file to its brand new cloned and generated 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,7 +325,6 @@ private:
|
|||||||
std::string ClangModuleName;
|
std::string ClangModuleName;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace dsymutil
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
#endif // LLVM_TOOLS_DSYMUTIL_COMPILEUNIT_H
|
#endif // LLVM_DWARFLINKER_DWARFLINKERCOMPILEUNIT_H
|
@ -1,4 +1,4 @@
|
|||||||
//===- tools/dsymutil/DeclContext.h - Dwarf debug info linker ---*- C++ -*-===//
|
//===- DWARFLinkerDeclContext.h ---------------------------------*- 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,20 +6,19 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
|
#ifndef LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_H
|
||||||
#define LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
|
#define LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_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/DWARFLinker/DWARFLinkerCompileUnit.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
|
||||||
#include "llvm/Support/Path.h"
|
#include "llvm/Support/Path.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
namespace dsymutil {
|
|
||||||
|
|
||||||
struct DeclMapInfo;
|
struct DeclMapInfo;
|
||||||
|
|
||||||
@ -165,7 +164,6 @@ struct DeclMapInfo : private DenseMapInfo<DeclContext *> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace dsymutil
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
#endif // LLVM_TOOLS_DSYMUTIL_DECLCONTEXT_H
|
#endif // LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_H
|
@ -8,6 +8,7 @@ add_subdirectory(CodeGen)
|
|||||||
add_subdirectory(BinaryFormat)
|
add_subdirectory(BinaryFormat)
|
||||||
add_subdirectory(Bitcode)
|
add_subdirectory(Bitcode)
|
||||||
add_subdirectory(Bitstream)
|
add_subdirectory(Bitstream)
|
||||||
|
add_subdirectory(DWARFLinker)
|
||||||
add_subdirectory(Frontend)
|
add_subdirectory(Frontend)
|
||||||
add_subdirectory(Transforms)
|
add_subdirectory(Transforms)
|
||||||
add_subdirectory(Linker)
|
add_subdirectory(Linker)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//===-- llvm/CodeGen/NonRelocatableStringpool.cpp - A simple stringpool --===//
|
//===-- NonRelocatableStringpool.cpp --------------------------------------===//
|
||||||
//
|
//
|
||||||
// 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
lib/DWARFLinker/CMakeLists.txt
Normal file
6
lib/DWARFLinker/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
add_llvm_component_library(LLVMDWARFLinker
|
||||||
|
DWARFLinkerCompileUnit.cpp
|
||||||
|
DWARFLinkerDeclContext.cpp
|
||||||
|
DWARFLinker.cpp
|
||||||
|
|
||||||
|
)
|
15
lib/DWARFLinker/DWARFLinker.cpp
Normal file
15
lib/DWARFLinker/DWARFLinker.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//=== DWARFLinker.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/DWARFLinker/DWARFLinker.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
AddressesMap::~AddressesMap() {}
|
||||||
|
|
||||||
|
} // namespace llvm
|
@ -1,4 +1,4 @@
|
|||||||
//===- tools/dsymutil/CompileUnit.h - Dwarf compile unit ------------------===//
|
//===- DWARFLinkerCompileUnit.cpp -----------------------------------------===//
|
||||||
//
|
//
|
||||||
// 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,11 +6,10 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "CompileUnit.h"
|
#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
|
||||||
#include "DeclContext.h"
|
#include "llvm/DWARFLinker/DWARFLinkerDeclContext.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) {
|
||||||
@ -142,5 +141,4 @@ 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 @@
|
|||||||
//===- tools/dsymutil/DeclContext.cpp - Declaration context ---------------===//
|
//===- DWARFLinkerDeclContext.cpp -----------------------------------------===//
|
||||||
//
|
//
|
||||||
// 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,13 +6,12 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "DeclContext.h"
|
#include "llvm/DWARFLinker/DWARFLinkerDeclContext.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.
|
||||||
@ -206,5 +205,5 @@ PointerIntPair<DeclContext *, 1> DeclContextTree::getChildDeclContext(
|
|||||||
|
|
||||||
return PointerIntPair<DeclContext *, 1>(*ContextIter);
|
return PointerIntPair<DeclContext *, 1>(*ContextIter);
|
||||||
}
|
}
|
||||||
} // namespace dsymutil
|
|
||||||
} // namespace llvm
|
} // namespace llvm
|
21
lib/DWARFLinker/LLVMBuild.txt
Normal file
21
lib/DWARFLinker/LLVMBuild.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
;===- ./lib/DWARFLinker/LLVMBuild.txt ---------------*- Conf -*--===;
|
||||||
|
;
|
||||||
|
; 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
|
||||||
|
;
|
||||||
|
;===------------------------------------------------------------------------===;
|
||||||
|
;
|
||||||
|
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||||
|
;
|
||||||
|
; For more information on the LLVMBuild system, please see:
|
||||||
|
;
|
||||||
|
; http://llvm.org/docs/LLVMBuild.html
|
||||||
|
;
|
||||||
|
;===------------------------------------------------------------------------===;
|
||||||
|
|
||||||
|
[component_0]
|
||||||
|
type = Library
|
||||||
|
name = DWARFLinker
|
||||||
|
parent = Libraries
|
||||||
|
required_libraries = DebugInfoDWARF AsmPrinter CodeGen MC Object Support
|
@ -23,6 +23,7 @@ subdirectories =
|
|||||||
CodeGen
|
CodeGen
|
||||||
DebugInfo
|
DebugInfo
|
||||||
Demangle
|
Demangle
|
||||||
|
DWARFLinker
|
||||||
ExecutionEngine
|
ExecutionEngine
|
||||||
Frontend
|
Frontend
|
||||||
FuzzMutate
|
FuzzMutate
|
||||||
|
@ -9,6 +9,7 @@ set(LLVM_LINK_COMPONENTS
|
|||||||
AllTargetsInfos
|
AllTargetsInfos
|
||||||
AsmPrinter
|
AsmPrinter
|
||||||
DebugInfoDWARF
|
DebugInfoDWARF
|
||||||
|
DWARFLinker
|
||||||
MC
|
MC
|
||||||
Object
|
Object
|
||||||
CodeGen
|
CodeGen
|
||||||
@ -22,10 +23,8 @@ add_llvm_tool(dsymutil
|
|||||||
dsymutil.cpp
|
dsymutil.cpp
|
||||||
BinaryHolder.cpp
|
BinaryHolder.cpp
|
||||||
CFBundle.cpp
|
CFBundle.cpp
|
||||||
CompileUnit.cpp
|
|
||||||
DebugMap.cpp
|
DebugMap.cpp
|
||||||
DeclContext.cpp
|
DwarfLinkerForBinary.cpp
|
||||||
DwarfLinker.cpp
|
|
||||||
DwarfStreamer.cpp
|
DwarfStreamer.cpp
|
||||||
MachODebugMapParser.cpp
|
MachODebugMapParser.cpp
|
||||||
MachOUtils.cpp
|
MachOUtils.cpp
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//===- tools/dsymutil/DwarfLinker.cpp - Dwarf debug info linker -----------===//
|
//===- tools/dsymutil/DwarfLinkerForBinary.cpp ----------------------------===//
|
||||||
//
|
//
|
||||||
// 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,9 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "DwarfLinker.h"
|
#include "DwarfLinkerForBinary.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"
|
||||||
@ -37,6 +36,7 @@
|
|||||||
#include "llvm/CodeGen/DIE.h"
|
#include "llvm/CodeGen/DIE.h"
|
||||||
#include "llvm/CodeGen/NonRelocatableStringpool.h"
|
#include "llvm/CodeGen/NonRelocatableStringpool.h"
|
||||||
#include "llvm/Config/config.h"
|
#include "llvm/Config/config.h"
|
||||||
|
#include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
|
||||||
#include "llvm/DebugInfo/DIContext.h"
|
#include "llvm/DebugInfo/DIContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
|
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
@ -119,7 +119,7 @@ static CompileUnit *getUnitForOffset(const UnitListTy &Units, uint64_t Offset) {
|
|||||||
/// Resolve the DIE attribute reference that has been extracted in \p RefValue.
|
/// Resolve the DIE attribute reference that has been extracted in \p RefValue.
|
||||||
/// The resulting DIE might be in another CompileUnit which is stored into \p
|
/// The resulting DIE might be in another CompileUnit which is stored into \p
|
||||||
/// ReferencedCU. \returns null if resolving fails for any reason.
|
/// ReferencedCU. \returns null if resolving fails for any reason.
|
||||||
static DWARFDie resolveDIEReference(const DwarfLinker &Linker,
|
static DWARFDie resolveDIEReference(const DwarfLinkerForBinary &Linker,
|
||||||
const DebugMapObject &DMO,
|
const DebugMapObject &DMO,
|
||||||
const UnitListTy &Units,
|
const UnitListTy &Units,
|
||||||
const DWARFFormValue &RefValue,
|
const DWARFFormValue &RefValue,
|
||||||
@ -188,7 +188,8 @@ static bool isTypeTag(uint16_t Tag) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Error remarksErrorHandler(const DebugMapObject &DMO, DwarfLinker &Linker,
|
static Error remarksErrorHandler(const DebugMapObject &DMO,
|
||||||
|
DwarfLinkerForBinary &Linker,
|
||||||
std::unique_ptr<FileError> FE) {
|
std::unique_ptr<FileError> FE) {
|
||||||
bool IsArchive = DMO.getObjectFilename().endswith(")");
|
bool IsArchive = DMO.getObjectFilename().endswith(")");
|
||||||
// Don't report errors for missing remark files from static
|
// Don't report errors for missing remark files from static
|
||||||
@ -212,10 +213,10 @@ static Error remarksErrorHandler(const DebugMapObject &DMO, DwarfLinker &Linker,
|
|||||||
return createFileError(FE->getFileName(), std::move(NewE));
|
return createFileError(FE->getFileName(), std::move(NewE));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DwarfLinker::DIECloner::getDIENames(const DWARFDie &Die,
|
bool DwarfLinkerForBinary::DIECloner::getDIENames(const DWARFDie &Die,
|
||||||
AttributesInfo &Info,
|
AttributesInfo &Info,
|
||||||
OffsetsStringPool &StringPool,
|
OffsetsStringPool &StringPool,
|
||||||
bool StripTemplate) {
|
bool StripTemplate) {
|
||||||
// This function will be called on DIEs having low_pcs and
|
// This function will be called on DIEs having low_pcs and
|
||||||
// ranges. As getting the name might be more expansive, filter out
|
// ranges. As getting the name might be more expansive, filter out
|
||||||
// blocks directly.
|
// blocks directly.
|
||||||
@ -244,8 +245,9 @@ bool DwarfLinker::DIECloner::getDIENames(const DWARFDie &Die,
|
|||||||
|
|
||||||
/// Report a warning to the user, optionally including information about a
|
/// Report a warning to the user, optionally including information about a
|
||||||
/// specific \p DIE related to the warning.
|
/// specific \p DIE related to the warning.
|
||||||
void DwarfLinker::reportWarning(const Twine &Warning, const DebugMapObject &DMO,
|
void DwarfLinkerForBinary::reportWarning(const Twine &Warning,
|
||||||
const DWARFDie *DIE) const {
|
const DebugMapObject &DMO,
|
||||||
|
const DWARFDie *DIE) const {
|
||||||
StringRef Context = DMO.getObjectFilename();
|
StringRef Context = DMO.getObjectFilename();
|
||||||
warn(Warning, Context);
|
warn(Warning, Context);
|
||||||
|
|
||||||
@ -260,8 +262,8 @@ void DwarfLinker::reportWarning(const Twine &Warning, const DebugMapObject &DMO,
|
|||||||
DIE->dump(errs(), 6 /* Indent */, DumpOpts);
|
DIE->dump(errs(), 6 /* Indent */, DumpOpts);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DwarfLinker::createStreamer(const Triple &TheTriple,
|
bool DwarfLinkerForBinary::createStreamer(const Triple &TheTriple,
|
||||||
raw_fd_ostream &OutFile) {
|
raw_fd_ostream &OutFile) {
|
||||||
if (Options.NoOutput)
|
if (Options.NoOutput)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -397,34 +399,9 @@ static bool dieNeedsChildrenToBeMeaningful(uint32_t Tag) {
|
|||||||
llvm_unreachable("Invalid Tag");
|
llvm_unreachable("Invalid Tag");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfLinker::startDebugObject(LinkContext &Context) {
|
void DwarfLinkerForBinary::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 DwarfLinkerForBinary::endDebugObject(LinkContext &Context) {
|
||||||
Context.Clear();
|
Context.Clear();
|
||||||
|
|
||||||
for (auto I = DIEBlocks.begin(), E = DIEBlocks.end(); I != E; ++I)
|
for (auto I = DIEBlocks.begin(), E = DIEBlocks.end(); I != E; ++I)
|
||||||
@ -460,7 +437,7 @@ static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) {
|
|||||||
/// Iterate over the relocations of the given \p Section and
|
/// Iterate over the relocations of the given \p Section and
|
||||||
/// store the ones that correspond to debug map entries into the
|
/// store the ones that correspond to debug map entries into the
|
||||||
/// ValidRelocs array.
|
/// ValidRelocs array.
|
||||||
void DwarfLinker::RelocationManager::findValidRelocsMachO(
|
void DwarfLinkerForBinary::RelocationManager::findValidRelocsMachO(
|
||||||
const object::SectionRef &Section, const object::MachOObjectFile &Obj,
|
const object::SectionRef &Section, const object::MachOObjectFile &Obj,
|
||||||
const DebugMapObject &DMO) {
|
const DebugMapObject &DMO) {
|
||||||
Expected<StringRef> ContentsOrErr = Section.getContents();
|
Expected<StringRef> ContentsOrErr = Section.getContents();
|
||||||
@ -534,7 +511,7 @@ void DwarfLinker::RelocationManager::findValidRelocsMachO(
|
|||||||
|
|
||||||
/// Dispatch the valid relocation finding logic to the
|
/// Dispatch the valid relocation finding logic to the
|
||||||
/// appropriate handler depending on the object file format.
|
/// appropriate handler depending on the object file format.
|
||||||
bool DwarfLinker::RelocationManager::findValidRelocs(
|
bool DwarfLinkerForBinary::RelocationManager::findValidRelocs(
|
||||||
const object::SectionRef &Section, const object::ObjectFile &Obj,
|
const object::SectionRef &Section, const object::ObjectFile &Obj,
|
||||||
const DebugMapObject &DMO) {
|
const DebugMapObject &DMO) {
|
||||||
// Dispatch to the right handler depending on the file type.
|
// Dispatch to the right handler depending on the file type.
|
||||||
@ -560,7 +537,7 @@ bool DwarfLinker::RelocationManager::findValidRelocs(
|
|||||||
/// link by indicating which DIEs refer to symbols present in the
|
/// link by indicating which DIEs refer to symbols present in the
|
||||||
/// linked binary.
|
/// linked binary.
|
||||||
/// \returns whether there are any valid relocations in the debug info.
|
/// \returns whether there are any valid relocations in the debug info.
|
||||||
bool DwarfLinker::RelocationManager::findValidRelocsInDebugInfo(
|
bool DwarfLinkerForBinary::RelocationManager::findValidRelocsInDebugInfo(
|
||||||
const object::ObjectFile &Obj, const DebugMapObject &DMO) {
|
const object::ObjectFile &Obj, const DebugMapObject &DMO) {
|
||||||
// Find the debug_info section.
|
// Find the debug_info section.
|
||||||
for (const object::SectionRef &Section : Obj.sections()) {
|
for (const object::SectionRef &Section : Obj.sections()) {
|
||||||
@ -584,7 +561,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::hasValidRelocation(
|
bool DwarfLinkerForBinary::RelocationManager::hasValidRelocationAt(
|
||||||
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);
|
||||||
@ -645,11 +622,9 @@ getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx,
|
|||||||
|
|
||||||
/// Check if a variable describing DIE should be kept.
|
/// Check if a variable describing DIE should be kept.
|
||||||
/// \returns updated TraversalFlags.
|
/// \returns updated TraversalFlags.
|
||||||
unsigned DwarfLinker::shouldKeepVariableDIE(RelocationManager &RelocMgr,
|
unsigned DwarfLinkerForBinary::shouldKeepVariableDIE(
|
||||||
const DWARFDie &DIE,
|
RelocationManager &RelocMgr, const DWARFDie &DIE, CompileUnit &Unit,
|
||||||
CompileUnit &Unit,
|
CompileUnit::DIEInfo &MyInfo, unsigned Flags) {
|
||||||
CompileUnit::DIEInfo &MyInfo,
|
|
||||||
unsigned Flags) {
|
|
||||||
const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
|
const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
|
||||||
|
|
||||||
// Global variables with constant value can always be kept.
|
// Global variables with constant value can always be kept.
|
||||||
@ -675,7 +650,8 @@ 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.hasValidRelocation(LocationOffset, LocationEndOffset, MyInfo) ||
|
if (!RelocMgr.hasValidRelocationAt(LocationOffset, LocationEndOffset,
|
||||||
|
MyInfo) ||
|
||||||
(Flags & TF_InFunctionScope))
|
(Flags & TF_InFunctionScope))
|
||||||
return Flags;
|
return Flags;
|
||||||
|
|
||||||
@ -692,7 +668,7 @@ unsigned DwarfLinker::shouldKeepVariableDIE(RelocationManager &RelocMgr,
|
|||||||
|
|
||||||
/// Check if a function describing DIE should be kept.
|
/// Check if a function describing DIE should be kept.
|
||||||
/// \returns updated TraversalFlags.
|
/// \returns updated TraversalFlags.
|
||||||
unsigned DwarfLinker::shouldKeepSubprogramDIE(
|
unsigned DwarfLinkerForBinary::shouldKeepSubprogramDIE(
|
||||||
RelocationManager &RelocMgr, RangesTy &Ranges, const DWARFDie &DIE,
|
RelocationManager &RelocMgr, RangesTy &Ranges, const DWARFDie &DIE,
|
||||||
const DebugMapObject &DMO, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
|
const DebugMapObject &DMO, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
|
||||||
unsigned Flags) {
|
unsigned Flags) {
|
||||||
@ -713,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.hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo))
|
!RelocMgr.hasValidRelocationAt(LowPcOffset, LowPcEndOffset, MyInfo))
|
||||||
return Flags;
|
return Flags;
|
||||||
|
|
||||||
if (Options.Verbose) {
|
if (Options.Verbose) {
|
||||||
@ -748,19 +724,17 @@ 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] = DebugMapObjectRange(*HighPc, MyInfo.AddrAdjust);
|
Ranges[*LowPc] = ObjFileAddressRange(*HighPc, MyInfo.AddrAdjust);
|
||||||
Unit.addFunctionRange(*LowPc, *HighPc, MyInfo.AddrAdjust);
|
Unit.addFunctionRange(*LowPc, *HighPc, MyInfo.AddrAdjust);
|
||||||
return Flags;
|
return Flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a DIE should be kept.
|
/// Check if a DIE should be kept.
|
||||||
/// \returns updated TraversalFlags.
|
/// \returns updated TraversalFlags.
|
||||||
unsigned DwarfLinker::shouldKeepDIE(RelocationManager &RelocMgr,
|
unsigned DwarfLinkerForBinary::shouldKeepDIE(
|
||||||
RangesTy &Ranges, const DWARFDie &DIE,
|
RelocationManager &RelocMgr, RangesTy &Ranges, const DWARFDie &DIE,
|
||||||
const DebugMapObject &DMO,
|
const DebugMapObject &DMO, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
|
||||||
CompileUnit &Unit,
|
unsigned Flags) {
|
||||||
CompileUnit::DIEInfo &MyInfo,
|
|
||||||
unsigned Flags) {
|
|
||||||
switch (DIE.getTag()) {
|
switch (DIE.getTag()) {
|
||||||
case dwarf::DW_TAG_constant:
|
case dwarf::DW_TAG_constant:
|
||||||
case dwarf::DW_TAG_variable:
|
case dwarf::DW_TAG_variable:
|
||||||
@ -885,11 +859,11 @@ static void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
|
|||||||
// the parent chain). There are however a set of DIE types for which we want
|
// the parent chain). There are however a set of DIE types for which we want
|
||||||
// to ignore that directive and still walk their children.
|
// to ignore that directive and still walk their children.
|
||||||
if (dieNeedsChildrenToBeMeaningful(Die.getTag()))
|
if (dieNeedsChildrenToBeMeaningful(Die.getTag()))
|
||||||
Flags &= ~DwarfLinker::TF_ParentWalk;
|
Flags &= ~DwarfLinkerForBinary::TF_ParentWalk;
|
||||||
|
|
||||||
// We're finished if this DIE has no children or we're walking the parent
|
// We're finished if this DIE has no children or we're walking the parent
|
||||||
// chain.
|
// chain.
|
||||||
if (!Die.hasChildren() || (Flags & DwarfLinker::TF_ParentWalk))
|
if (!Die.hasChildren() || (Flags & DwarfLinkerForBinary::TF_ParentWalk))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Add children in reverse order to the worklist to effectively process them
|
// Add children in reverse order to the worklist to effectively process them
|
||||||
@ -908,12 +882,12 @@ static void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
|
|||||||
/// Look at DIEs referenced by the given DIE and decide whether they should be
|
/// Look at DIEs referenced by the given DIE and decide whether they should be
|
||||||
/// kept. All DIEs referenced though attributes should be kept.
|
/// kept. All DIEs referenced though attributes should be kept.
|
||||||
static void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
|
static void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
|
||||||
unsigned Flags, DwarfLinker &Linker,
|
unsigned Flags, DwarfLinkerForBinary &Linker,
|
||||||
const UnitListTy &Units,
|
const UnitListTy &Units,
|
||||||
const DebugMapObject &DMO,
|
const DebugMapObject &DMO,
|
||||||
SmallVectorImpl<WorklistItem> &Worklist) {
|
SmallVectorImpl<WorklistItem> &Worklist) {
|
||||||
bool UseOdr = (Flags & DwarfLinker::TF_DependencyWalk)
|
bool UseOdr = (Flags & DwarfLinkerForBinary::TF_DependencyWalk)
|
||||||
? (Flags & DwarfLinker::TF_ODR)
|
? (Flags & DwarfLinkerForBinary::TF_ODR)
|
||||||
: CU.hasODR();
|
: CU.hasODR();
|
||||||
DWARFUnit &Unit = CU.getOrigUnit();
|
DWARFUnit &Unit = CU.getOrigUnit();
|
||||||
DWARFDataExtractor Data = Unit.getDebugInfoExtractor();
|
DWARFDataExtractor Data = Unit.getDebugInfoExtractor();
|
||||||
@ -962,7 +936,7 @@ static void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ODRFlag = UseOdr ? DwarfLinker::TF_ODR : 0;
|
unsigned ODRFlag = UseOdr ? DwarfLinkerForBinary::TF_ODR : 0;
|
||||||
|
|
||||||
// Add referenced DIEs in reverse order to the worklist to effectively
|
// Add referenced DIEs in reverse order to the worklist to effectively
|
||||||
// process them in order.
|
// process them in order.
|
||||||
@ -974,8 +948,9 @@ static void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
|
|||||||
Worklist.emplace_back(Die, CU, WorklistItemType::UpdateRefIncompleteness,
|
Worklist.emplace_back(Die, CU, WorklistItemType::UpdateRefIncompleteness,
|
||||||
&Info);
|
&Info);
|
||||||
Worklist.emplace_back(P.first, P.second,
|
Worklist.emplace_back(P.first, P.second,
|
||||||
DwarfLinker::TF_Keep |
|
DwarfLinkerForBinary::TF_Keep |
|
||||||
DwarfLinker::TF_DependencyWalk | ODRFlag);
|
DwarfLinkerForBinary::TF_DependencyWalk |
|
||||||
|
ODRFlag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1018,11 +993,12 @@ static void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU,
|
|||||||
/// UpdateRefIncompleteness).
|
/// UpdateRefIncompleteness).
|
||||||
///
|
///
|
||||||
/// The return value indicates whether the DIE is incomplete.
|
/// The return value indicates whether the DIE is incomplete.
|
||||||
void DwarfLinker::lookForDIEsToKeep(RelocationManager &RelocMgr,
|
void DwarfLinkerForBinary::lookForDIEsToKeep(RelocationManager &RelocMgr,
|
||||||
RangesTy &Ranges, const UnitListTy &Units,
|
RangesTy &Ranges,
|
||||||
const DWARFDie &Die,
|
const UnitListTy &Units,
|
||||||
const DebugMapObject &DMO, CompileUnit &Cu,
|
const DWARFDie &Die,
|
||||||
unsigned Flags) {
|
const DebugMapObject &DMO,
|
||||||
|
CompileUnit &Cu, unsigned Flags) {
|
||||||
// LIFO work list.
|
// LIFO work list.
|
||||||
SmallVector<WorklistItem, 4> Worklist;
|
SmallVector<WorklistItem, 4> Worklist;
|
||||||
Worklist.emplace_back(Die, Cu, Flags);
|
Worklist.emplace_back(Die, Cu, Flags);
|
||||||
@ -1113,7 +1089,7 @@ void DwarfLinker::lookForDIEsToKeep(RelocationManager &RelocMgr,
|
|||||||
/// thus the FoldingSet we use to unique DIEAbbrevs cannot refer to
|
/// thus the FoldingSet we use to unique DIEAbbrevs cannot refer to
|
||||||
/// the instances hold by the DIEs. When we encounter an abbreviation
|
/// the instances hold by the DIEs. When we encounter an abbreviation
|
||||||
/// that we don't know, we create a permanent copy of it.
|
/// that we don't know, we create a permanent copy of it.
|
||||||
void DwarfLinker::AssignAbbrev(DIEAbbrev &Abbrev) {
|
void DwarfLinkerForBinary::assignAbbrev(DIEAbbrev &Abbrev) {
|
||||||
// Check the set for priors.
|
// Check the set for priors.
|
||||||
FoldingSetNodeID ID;
|
FoldingSetNodeID ID;
|
||||||
Abbrev.Profile(ID);
|
Abbrev.Profile(ID);
|
||||||
@ -1137,7 +1113,7 @@ void DwarfLinker::AssignAbbrev(DIEAbbrev &Abbrev) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned DwarfLinker::DIECloner::cloneStringAttribute(
|
unsigned DwarfLinkerForBinary::DIECloner::cloneStringAttribute(
|
||||||
DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
|
DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
|
||||||
const DWARFUnit &U, OffsetsStringPool &StringPool, AttributesInfo &Info) {
|
const DWARFUnit &U, OffsetsStringPool &StringPool, AttributesInfo &Info) {
|
||||||
// Switch everything to out of line strings.
|
// Switch everything to out of line strings.
|
||||||
@ -1157,7 +1133,7 @@ unsigned DwarfLinker::DIECloner::cloneStringAttribute(
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned DwarfLinker::DIECloner::cloneDieReferenceAttribute(
|
unsigned DwarfLinkerForBinary::DIECloner::cloneDieReferenceAttribute(
|
||||||
DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec,
|
DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec,
|
||||||
unsigned AttrSize, const DWARFFormValue &Val, const DebugMapObject &DMO,
|
unsigned AttrSize, const DWARFFormValue &Val, const DebugMapObject &DMO,
|
||||||
CompileUnit &Unit) {
|
CompileUnit &Unit) {
|
||||||
@ -1228,7 +1204,7 @@ unsigned DwarfLinker::DIECloner::cloneDieReferenceAttribute(
|
|||||||
return AttrSize;
|
return AttrSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfLinker::DIECloner::cloneExpression(
|
void DwarfLinkerForBinary::DIECloner::cloneExpression(
|
||||||
DataExtractor &Data, DWARFExpression Expression, const DebugMapObject &DMO,
|
DataExtractor &Data, DWARFExpression Expression, const DebugMapObject &DMO,
|
||||||
CompileUnit &Unit, SmallVectorImpl<uint8_t> &OutputBuffer) {
|
CompileUnit &Unit, SmallVectorImpl<uint8_t> &OutputBuffer) {
|
||||||
using Encoding = DWARFExpression::Operation::Encoding;
|
using Encoding = DWARFExpression::Operation::Encoding;
|
||||||
@ -1288,7 +1264,7 @@ void DwarfLinker::DIECloner::cloneExpression(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned DwarfLinker::DIECloner::cloneBlockAttribute(
|
unsigned DwarfLinkerForBinary::DIECloner::cloneBlockAttribute(
|
||||||
DIE &Die, const DebugMapObject &DMO, CompileUnit &Unit,
|
DIE &Die, const DebugMapObject &DMO, CompileUnit &Unit,
|
||||||
AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize,
|
AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize,
|
||||||
bool IsLittleEndian) {
|
bool IsLittleEndian) {
|
||||||
@ -1346,7 +1322,7 @@ unsigned DwarfLinker::DIECloner::cloneBlockAttribute(
|
|||||||
return AttrSize;
|
return AttrSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned DwarfLinker::DIECloner::cloneAddressAttribute(
|
unsigned DwarfLinkerForBinary::DIECloner::cloneAddressAttribute(
|
||||||
DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
|
DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
|
||||||
const CompileUnit &Unit, AttributesInfo &Info) {
|
const CompileUnit &Unit, AttributesInfo &Info) {
|
||||||
uint64_t Addr = *Val.getAsAddress();
|
uint64_t Addr = *Val.getAsAddress();
|
||||||
@ -1394,7 +1370,7 @@ unsigned DwarfLinker::DIECloner::cloneAddressAttribute(
|
|||||||
return Unit.getOrigUnit().getAddressByteSize();
|
return Unit.getOrigUnit().getAddressByteSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned DwarfLinker::DIECloner::cloneScalarAttribute(
|
unsigned DwarfLinkerForBinary::DIECloner::cloneScalarAttribute(
|
||||||
DIE &Die, const DWARFDie &InputDIE, const DebugMapObject &DMO,
|
DIE &Die, const DWARFDie &InputDIE, const DebugMapObject &DMO,
|
||||||
CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val,
|
CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val,
|
||||||
unsigned AttrSize, AttributesInfo &Info) {
|
unsigned AttrSize, AttributesInfo &Info) {
|
||||||
@ -1451,7 +1427,7 @@ unsigned DwarfLinker::DIECloner::cloneScalarAttribute(
|
|||||||
// location list.
|
// location list.
|
||||||
// FIXME: use DWARFAttribute::mayHaveLocationDescription().
|
// FIXME: use DWARFAttribute::mayHaveLocationDescription().
|
||||||
else if (AttrSpec.Attr == dwarf::DW_AT_location ||
|
else if (AttrSpec.Attr == dwarf::DW_AT_location ||
|
||||||
AttrSpec.Attr == dwarf::DW_AT_frame_base)
|
AttrSpec.Attr == dwarf::DW_AT_frame_base)
|
||||||
Unit.noteLocationAttribute(Patch, Info.PCOffset);
|
Unit.noteLocationAttribute(Patch, Info.PCOffset);
|
||||||
else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
|
else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
|
||||||
Info.IsDeclaration = true;
|
Info.IsDeclaration = true;
|
||||||
@ -1462,7 +1438,7 @@ unsigned DwarfLinker::DIECloner::cloneScalarAttribute(
|
|||||||
/// Clone \p InputDIE's attribute described by \p AttrSpec with
|
/// Clone \p InputDIE's attribute described by \p AttrSpec with
|
||||||
/// value \p Val, and add it to \p Die.
|
/// value \p Val, and add it to \p Die.
|
||||||
/// \returns the size of the cloned attribute.
|
/// \returns the size of the cloned attribute.
|
||||||
unsigned DwarfLinker::DIECloner::cloneAttribute(
|
unsigned DwarfLinkerForBinary::DIECloner::cloneAttribute(
|
||||||
DIE &Die, const DWARFDie &InputDIE, const DebugMapObject &DMO,
|
DIE &Die, const DWARFDie &InputDIE, const DebugMapObject &DMO,
|
||||||
CompileUnit &Unit, OffsetsStringPool &StringPool, const DWARFFormValue &Val,
|
CompileUnit &Unit, OffsetsStringPool &StringPool, const DWARFFormValue &Val,
|
||||||
const AttributeSpec AttrSpec, unsigned AttrSize, AttributesInfo &Info,
|
const AttributeSpec AttrSpec, unsigned AttrSize, AttributesInfo &Info,
|
||||||
@ -1517,7 +1493,7 @@ unsigned DwarfLinker::DIECloner::cloneAttribute(
|
|||||||
/// monotonic \p BaseOffset values.
|
/// monotonic \p BaseOffset values.
|
||||||
///
|
///
|
||||||
/// \returns whether any reloc has been applied.
|
/// \returns whether any reloc has been applied.
|
||||||
bool DwarfLinker::RelocationManager::applyValidRelocs(
|
bool DwarfLinkerForBinary::RelocationManager::applyValidRelocs(
|
||||||
MutableArrayRef<char> Data, uint64_t BaseOffset, bool IsLittleEndian) {
|
MutableArrayRef<char> Data, uint64_t BaseOffset, bool IsLittleEndian) {
|
||||||
assert((NextValidReloc == 0 ||
|
assert((NextValidReloc == 0 ||
|
||||||
BaseOffset > ValidRelocs[NextValidReloc - 1].Offset) &&
|
BaseOffset > ValidRelocs[NextValidReloc - 1].Offset) &&
|
||||||
@ -1558,11 +1534,9 @@ static bool isObjCSelector(StringRef Name) {
|
|||||||
(Name[1] == '[');
|
(Name[1] == '[');
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfLinker::DIECloner::addObjCAccelerator(CompileUnit &Unit,
|
void DwarfLinkerForBinary::DIECloner::addObjCAccelerator(
|
||||||
const DIE *Die,
|
CompileUnit &Unit, const DIE *Die, DwarfStringPoolEntryRef Name,
|
||||||
DwarfStringPoolEntryRef Name,
|
OffsetsStringPool &StringPool, bool SkipPubSection) {
|
||||||
OffsetsStringPool &StringPool,
|
|
||||||
bool SkipPubSection) {
|
|
||||||
assert(isObjCSelector(Name.getString()) && "not an objc selector");
|
assert(isObjCSelector(Name.getString()) && "not an objc selector");
|
||||||
// Objective C method or class function.
|
// Objective C method or class function.
|
||||||
// "- [Class(Category) selector :withArg ...]"
|
// "- [Class(Category) selector :withArg ...]"
|
||||||
@ -1624,7 +1598,7 @@ shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DIE *DwarfLinker::DIECloner::cloneDIE(
|
DIE *DwarfLinkerForBinary::DIECloner::cloneDIE(
|
||||||
const DWARFDie &InputDIE, const DebugMapObject &DMO, CompileUnit &Unit,
|
const DWARFDie &InputDIE, const DebugMapObject &DMO, CompileUnit &Unit,
|
||||||
OffsetsStringPool &StringPool, int64_t PCOffset, uint32_t OutOffset,
|
OffsetsStringPool &StringPool, int64_t PCOffset, uint32_t OutOffset,
|
||||||
unsigned Flags, bool IsLittleEndian, DIE *Die) {
|
unsigned Flags, bool IsLittleEndian, DIE *Die) {
|
||||||
@ -1675,7 +1649,8 @@ 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.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
|
// 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
|
||||||
@ -1793,7 +1768,7 @@ DIE *DwarfLinker::DIECloner::cloneDIE(
|
|||||||
if (HasChildren)
|
if (HasChildren)
|
||||||
NewAbbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
|
NewAbbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
|
||||||
// Assign a permanent abbrev number
|
// Assign a permanent abbrev number
|
||||||
Linker.AssignAbbrev(NewAbbrev);
|
Linker.assignAbbrev(NewAbbrev);
|
||||||
Die->setAbbrevNumber(NewAbbrev.getNumber());
|
Die->setAbbrevNumber(NewAbbrev.getNumber());
|
||||||
|
|
||||||
// Add the size of the abbreviation number to the output offset.
|
// Add the size of the abbreviation number to the output offset.
|
||||||
@ -1824,9 +1799,9 @@ DIE *DwarfLinker::DIECloner::cloneDIE(
|
|||||||
/// Patch the input object file relevant debug_ranges entries
|
/// Patch the input object file relevant debug_ranges entries
|
||||||
/// and emit them in the output file. Update the relevant attributes
|
/// and emit them in the output file. Update the relevant attributes
|
||||||
/// to point at the new entries.
|
/// to point at the new entries.
|
||||||
void DwarfLinker::patchRangesForUnit(const CompileUnit &Unit,
|
void DwarfLinkerForBinary::patchRangesForUnit(const CompileUnit &Unit,
|
||||||
DWARFContext &OrigDwarf,
|
DWARFContext &OrigDwarf,
|
||||||
const DebugMapObject &DMO) const {
|
const DebugMapObject &DMO) const {
|
||||||
DWARFDebugRangeList RangeList;
|
DWARFDebugRangeList RangeList;
|
||||||
const auto &FunctionRanges = Unit.getFunctionRanges();
|
const auto &FunctionRanges = Unit.getFunctionRanges();
|
||||||
unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
|
unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
|
||||||
@ -1879,7 +1854,7 @@ void DwarfLinker::patchRangesForUnit(const CompileUnit &Unit,
|
|||||||
/// FIXME: this could actually be done right in patchRangesForUnit,
|
/// FIXME: this could actually be done right in patchRangesForUnit,
|
||||||
/// but for the sake of initial bit-for-bit compatibility with legacy
|
/// but for the sake of initial bit-for-bit compatibility with legacy
|
||||||
/// dsymutil, we have to do it in a delayed pass.
|
/// dsymutil, we have to do it in a delayed pass.
|
||||||
void DwarfLinker::generateUnitRanges(CompileUnit &Unit) const {
|
void DwarfLinkerForBinary::generateUnitRanges(CompileUnit &Unit) const {
|
||||||
auto Attr = Unit.getUnitRangesAttribute();
|
auto Attr = Unit.getUnitRangesAttribute();
|
||||||
if (Attr)
|
if (Attr)
|
||||||
Attr->set(Streamer->getRangesSectionSize());
|
Attr->set(Streamer->getRangesSectionSize());
|
||||||
@ -1931,10 +1906,10 @@ static void patchStmtList(DIE &Die, DIEInteger Offset) {
|
|||||||
/// Extract the line table for \p Unit from \p OrigDwarf, and
|
/// Extract the line table for \p Unit from \p OrigDwarf, and
|
||||||
/// recreate a relocated version of these for the address ranges that
|
/// recreate a relocated version of these for the address ranges that
|
||||||
/// are present in the binary.
|
/// are present in the binary.
|
||||||
void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
|
void DwarfLinkerForBinary::patchLineTableForUnit(CompileUnit &Unit,
|
||||||
DWARFContext &OrigDwarf,
|
DWARFContext &OrigDwarf,
|
||||||
RangesTy &Ranges,
|
RangesTy &Ranges,
|
||||||
const DebugMapObject &DMO) {
|
const DebugMapObject &DMO) {
|
||||||
DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE();
|
DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE();
|
||||||
auto StmtList = dwarf::toSectionOffset(CUDie.find(dwarf::DW_AT_stmt_list));
|
auto StmtList = dwarf::toSectionOffset(CUDie.find(dwarf::DW_AT_stmt_list));
|
||||||
if (!StmtList)
|
if (!StmtList)
|
||||||
@ -2071,7 +2046,7 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
|
void DwarfLinkerForBinary::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
|
||||||
switch (Options.TheAccelTableKind) {
|
switch (Options.TheAccelTableKind) {
|
||||||
case AccelTableKind::Apple:
|
case AccelTableKind::Apple:
|
||||||
emitAppleAcceleratorEntriesForUnit(Unit);
|
emitAppleAcceleratorEntriesForUnit(Unit);
|
||||||
@ -2085,7 +2060,8 @@ void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfLinker::emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit) {
|
void DwarfLinkerForBinary::emitAppleAcceleratorEntriesForUnit(
|
||||||
|
CompileUnit &Unit) {
|
||||||
// Add namespaces.
|
// Add namespaces.
|
||||||
for (const auto &Namespace : Unit.getNamespaces())
|
for (const auto &Namespace : Unit.getNamespaces())
|
||||||
AppleNamespaces.addName(Namespace.Name,
|
AppleNamespaces.addName(Namespace.Name,
|
||||||
@ -2114,7 +2090,8 @@ void DwarfLinker::emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit) {
|
|||||||
AppleObjc.addName(ObjC.Name, ObjC.Die->getOffset() + Unit.getStartOffset());
|
AppleObjc.addName(ObjC.Name, ObjC.Die->getOffset() + Unit.getStartOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfLinker::emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit) {
|
void DwarfLinkerForBinary::emitDwarfAcceleratorEntriesForUnit(
|
||||||
|
CompileUnit &Unit) {
|
||||||
for (const auto &Namespace : Unit.getNamespaces())
|
for (const auto &Namespace : Unit.getNamespaces())
|
||||||
DebugNames.addName(Namespace.Name, Namespace.Die->getOffset(),
|
DebugNames.addName(Namespace.Name, Namespace.Die->getOffset(),
|
||||||
Namespace.Die->getTag(), Unit.getUniqueID());
|
Namespace.Die->getTag(), Unit.getUniqueID());
|
||||||
@ -2132,10 +2109,10 @@ void DwarfLinker::emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit) {
|
|||||||
/// This is actually pretty easy as the data of the CIEs and FDEs can
|
/// This is actually pretty easy as the data of the CIEs and FDEs can
|
||||||
/// be considered as black boxes and moved as is. The only thing to do
|
/// be considered as black boxes and moved as is. The only thing to do
|
||||||
/// is to patch the addresses in the headers.
|
/// is to patch the addresses in the headers.
|
||||||
void DwarfLinker::patchFrameInfoForObject(const DebugMapObject &DMO,
|
void DwarfLinkerForBinary::patchFrameInfoForObject(const DebugMapObject &DMO,
|
||||||
RangesTy &Ranges,
|
RangesTy &Ranges,
|
||||||
DWARFContext &OrigDwarf,
|
DWARFContext &OrigDwarf,
|
||||||
unsigned AddrSize) {
|
unsigned AddrSize) {
|
||||||
StringRef FrameData = OrigDwarf.getDWARFObj().getFrameSection().Data;
|
StringRef FrameData = OrigDwarf.getDWARFObj().getFrameSection().Data;
|
||||||
if (FrameData.empty())
|
if (FrameData.empty())
|
||||||
return;
|
return;
|
||||||
@ -2212,25 +2189,24 @@ void DwarfLinker::patchFrameInfoForObject(const DebugMapObject &DMO,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfLinker::DIECloner::copyAbbrev(
|
void DwarfLinkerForBinary::DIECloner::copyAbbrev(
|
||||||
const DWARFAbbreviationDeclaration &Abbrev, bool hasODR) {
|
const DWARFAbbreviationDeclaration &Abbrev, bool HasODR) {
|
||||||
DIEAbbrev Copy(dwarf::Tag(Abbrev.getTag()),
|
DIEAbbrev Copy(dwarf::Tag(Abbrev.getTag()),
|
||||||
dwarf::Form(Abbrev.hasChildren()));
|
dwarf::Form(Abbrev.hasChildren()));
|
||||||
|
|
||||||
for (const auto &Attr : Abbrev.attributes()) {
|
for (const auto &Attr : Abbrev.attributes()) {
|
||||||
uint16_t Form = Attr.Form;
|
uint16_t Form = Attr.Form;
|
||||||
if (hasODR && isODRAttribute(Attr.Attr))
|
if (HasODR && isODRAttribute(Attr.Attr))
|
||||||
Form = dwarf::DW_FORM_ref_addr;
|
Form = dwarf::DW_FORM_ref_addr;
|
||||||
Copy.AddAttribute(dwarf::Attribute(Attr.Attr), dwarf::Form(Form));
|
Copy.AddAttribute(dwarf::Attribute(Attr.Attr), dwarf::Form(Form));
|
||||||
}
|
}
|
||||||
|
|
||||||
Linker.AssignAbbrev(Copy);
|
Linker.assignAbbrev(Copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t DwarfLinkerForBinary::DIECloner::hashFullyQualifiedName(
|
||||||
DwarfLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
|
DWARFDie DIE, CompileUnit &U, const DebugMapObject &DMO,
|
||||||
const DebugMapObject &DMO,
|
int ChildRecurseDepth) {
|
||||||
int ChildRecurseDepth) {
|
|
||||||
const char *Name = nullptr;
|
const char *Name = nullptr;
|
||||||
DWARFUnit *OrigUnit = &U.getOrigUnit();
|
DWARFUnit *OrigUnit = &U.getOrigUnit();
|
||||||
CompileUnit *CU = &U;
|
CompileUnit *CU = &U;
|
||||||
@ -2281,7 +2257,7 @@ static uint64_t getDwoId(const DWARFDie &CUDie, const DWARFUnit &Unit) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DwarfLinker::registerModuleReference(
|
bool DwarfLinkerForBinary::registerModuleReference(
|
||||||
DWARFDie CUDie, const DWARFUnit &Unit, DebugMap &ModuleMap,
|
DWARFDie CUDie, const DWARFUnit &Unit, DebugMap &ModuleMap,
|
||||||
const DebugMapObject &DMO, RangesTy &Ranges, OffsetsStringPool &StringPool,
|
const DebugMapObject &DMO, RangesTy &Ranges, OffsetsStringPool &StringPool,
|
||||||
UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts,
|
UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts,
|
||||||
@ -2339,7 +2315,8 @@ bool DwarfLinker::registerModuleReference(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<const object::ObjectFile &>
|
ErrorOr<const object::ObjectFile &>
|
||||||
DwarfLinker::loadObject(const DebugMapObject &Obj, const DebugMap &Map) {
|
DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj,
|
||||||
|
const DebugMap &Map) {
|
||||||
auto ObjectEntry =
|
auto ObjectEntry =
|
||||||
BinHolder.getObjectEntry(Obj.getObjectFilename(), Obj.getTimestamp());
|
BinHolder.getObjectEntry(Obj.getObjectFilename(), Obj.getTimestamp());
|
||||||
if (!ObjectEntry) {
|
if (!ObjectEntry) {
|
||||||
@ -2360,7 +2337,7 @@ DwarfLinker::loadObject(const DebugMapObject &Obj, const DebugMap &Map) {
|
|||||||
return *Object;
|
return *Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error DwarfLinker::loadClangModule(
|
Error DwarfLinkerForBinary::loadClangModule(
|
||||||
DWARFDie CUDie, StringRef Filename, StringRef ModuleName, uint64_t DwoId,
|
DWARFDie CUDie, StringRef Filename, StringRef ModuleName, uint64_t DwoId,
|
||||||
DebugMap &ModuleMap, const DebugMapObject &DMO, RangesTy &Ranges,
|
DebugMap &ModuleMap, const DebugMapObject &DMO, RangesTy &Ranges,
|
||||||
OffsetsStringPool &StringPool, UniquingStringPool &UniquingStringPool,
|
OffsetsStringPool &StringPool, UniquingStringPool &UniquingStringPool,
|
||||||
@ -2417,7 +2394,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);
|
RelocationManager RelocMgr(*this, *ErrOrObj, DMO);
|
||||||
|
|
||||||
for (const auto &CU : DwarfContext->compile_units()) {
|
for (const auto &CU : DwarfContext->compile_units()) {
|
||||||
updateDwarfVersion(CU->getVersion());
|
updateDwarfVersion(CU->getVersion());
|
||||||
@ -2454,7 +2431,7 @@ Error DwarfLinker::loadClangModule(
|
|||||||
|
|
||||||
// Add this module.
|
// Add this module.
|
||||||
Unit = std::make_unique<CompileUnit>(*CU, UnitID++, !Options.NoODR,
|
Unit = std::make_unique<CompileUnit>(*CU, UnitID++, !Options.NoODR,
|
||||||
ModuleName);
|
ModuleName);
|
||||||
Unit->setHasInterestingContent();
|
Unit->setHasInterestingContent();
|
||||||
analyzeContextInfo(CUDie, 0, *Unit, &ODRContexts.getRoot(),
|
analyzeContextInfo(CUDie, 0, *Unit, &ODRContexts.getRoot(),
|
||||||
UniquingStringPool, ODRContexts, ModulesEndOffset,
|
UniquingStringPool, ODRContexts, ModulesEndOffset,
|
||||||
@ -2481,7 +2458,7 @@ Error DwarfLinker::loadClangModule(
|
|||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfLinker::DIECloner::cloneAllCompileUnits(
|
void DwarfLinkerForBinary::DIECloner::cloneAllCompileUnits(
|
||||||
DWARFContext &DwarfContext, const DebugMapObject &DMO, RangesTy &Ranges,
|
DWARFContext &DwarfContext, const DebugMapObject &DMO, RangesTy &Ranges,
|
||||||
OffsetsStringPool &StringPool, bool IsLittleEndian) {
|
OffsetsStringPool &StringPool, bool IsLittleEndian) {
|
||||||
if (!Linker.Streamer)
|
if (!Linker.Streamer)
|
||||||
@ -2550,7 +2527,7 @@ void DwarfLinker::DIECloner::cloneAllCompileUnits(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfLinker::updateAccelKind(DWARFContext &Dwarf) {
|
void DwarfLinkerForBinary::updateAccelKind(DWARFContext &Dwarf) {
|
||||||
if (Options.TheAccelTableKind != AccelTableKind::Default)
|
if (Options.TheAccelTableKind != AccelTableKind::Default)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -2564,15 +2541,14 @@ void DwarfLinker::updateAccelKind(DWARFContext &Dwarf) {
|
|||||||
AtLeastOneAppleAccelTable = true;
|
AtLeastOneAppleAccelTable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AtLeastOneDwarfAccelTable &&
|
if (!AtLeastOneDwarfAccelTable && !DwarfObj.getNamesSection().Data.empty()) {
|
||||||
!DwarfObj.getNamesSection().Data.empty()) {
|
|
||||||
AtLeastOneDwarfAccelTable = true;
|
AtLeastOneDwarfAccelTable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DwarfLinker::emitPaperTrailWarnings(const DebugMapObject &DMO,
|
bool DwarfLinkerForBinary::emitPaperTrailWarnings(
|
||||||
const DebugMap &Map,
|
const DebugMapObject &DMO, const DebugMap &Map,
|
||||||
OffsetsStringPool &StringPool) {
|
OffsetsStringPool &StringPool) {
|
||||||
if (DMO.getWarnings().empty() || !DMO.empty())
|
if (DMO.getWarnings().empty() || !DMO.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -2606,13 +2582,13 @@ bool DwarfLinker::emitPaperTrailWarnings(const DebugMapObject &DMO,
|
|||||||
DMO.getWarnings().size() * (4 + 1 + 4) +
|
DMO.getWarnings().size() * (4 + 1 + 4) +
|
||||||
1 /* End of children */;
|
1 /* End of children */;
|
||||||
DIEAbbrev Abbrev = CUDie->generateAbbrev();
|
DIEAbbrev Abbrev = CUDie->generateAbbrev();
|
||||||
AssignAbbrev(Abbrev);
|
assignAbbrev(Abbrev);
|
||||||
CUDie->setAbbrevNumber(Abbrev.getNumber());
|
CUDie->setAbbrevNumber(Abbrev.getNumber());
|
||||||
Size += getULEB128Size(Abbrev.getNumber());
|
Size += getULEB128Size(Abbrev.getNumber());
|
||||||
// Abbreviation ordering needed for classic compatibility.
|
// Abbreviation ordering needed for classic compatibility.
|
||||||
for (auto &Child : CUDie->children()) {
|
for (auto &Child : CUDie->children()) {
|
||||||
Abbrev = Child.generateAbbrev();
|
Abbrev = Child.generateAbbrev();
|
||||||
AssignAbbrev(Abbrev);
|
assignAbbrev(Abbrev);
|
||||||
Child.setAbbrevNumber(Abbrev.getNumber());
|
Child.setAbbrevNumber(Abbrev.getNumber());
|
||||||
Size += getULEB128Size(Abbrev.getNumber());
|
Size += getULEB128Size(Abbrev.getNumber());
|
||||||
}
|
}
|
||||||
@ -2657,17 +2633,15 @@ static Error copySwiftInterfaces(
|
|||||||
|
|
||||||
// copy_file attempts an APFS clone first, so this should be cheap.
|
// copy_file attempts an APFS clone first, so this should be cheap.
|
||||||
if ((EC = sys::fs::copy_file(InterfaceFile, Path.str())))
|
if ((EC = sys::fs::copy_file(InterfaceFile, Path.str())))
|
||||||
warn(Twine("cannot copy parseable Swift interface ") +
|
warn(Twine("cannot copy parseable Swift interface ") + InterfaceFile +
|
||||||
InterfaceFile + ": " +
|
": " + toString(errorCodeToError(EC)));
|
||||||
toString(errorCodeToError(EC)));
|
|
||||||
Path.resize(BaseLength);
|
Path.resize(BaseLength);
|
||||||
}
|
}
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath,
|
static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath,
|
||||||
StringRef ArchName,
|
StringRef ArchName, const remarks::RemarkLinker &RL) {
|
||||||
const remarks::RemarkLinker &RL) {
|
|
||||||
// Make sure we don't create the directories and the file if there is nothing
|
// Make sure we don't create the directories and the file if there is nothing
|
||||||
// to serialize.
|
// to serialize.
|
||||||
if (RL.empty())
|
if (RL.empty())
|
||||||
@ -2701,7 +2675,7 @@ static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath,
|
|||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DwarfLinker::link(const DebugMap &Map) {
|
bool DwarfLinkerForBinary::link(const DebugMap &Map) {
|
||||||
if (!createStreamer(Map.getTriple(), OutFile))
|
if (!createStreamer(Map.getTriple(), OutFile))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -2798,8 +2772,7 @@ 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.findValidRelocsInDebugInfo(
|
!LinkContext.RelocMgr->hasValidRelocs()) {
|
||||||
*LinkContext.ObjectFile, LinkContext.DMO)) {
|
|
||||||
if (Options.Verbose)
|
if (Options.Verbose)
|
||||||
outs() << "No valid relocations found. Skipping.\n";
|
outs() << "No valid relocations found. Skipping.\n";
|
||||||
|
|
||||||
@ -2916,7 +2889,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);
|
||||||
@ -2925,10 +2898,9 @@ 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.
|
||||||
LinkContext.RelocMgr.resetValidRelocs();
|
if (LinkContext.RelocMgr->hasValidRelocs() || LLVM_UNLIKELY(Options.Update))
|
||||||
if (LinkContext.RelocMgr.hasValidRelocs() || LLVM_UNLIKELY(Options.Update))
|
DIECloner(*this, *LinkContext.RelocMgr, DIEAlloc,
|
||||||
DIECloner(*this, LinkContext.RelocMgr, DIEAlloc, LinkContext.CompileUnits,
|
LinkContext.CompileUnits, Options)
|
||||||
Options)
|
|
||||||
.cloneAllCompileUnits(*LinkContext.DwarfContext, LinkContext.DMO,
|
.cloneAllCompileUnits(*LinkContext.DwarfContext, LinkContext.DMO,
|
||||||
LinkContext.Ranges, OffsetsStringPool,
|
LinkContext.Ranges, OffsetsStringPool,
|
||||||
LinkContext.DwarfContext->isLittleEndian());
|
LinkContext.DwarfContext->isLittleEndian());
|
||||||
@ -3074,7 +3046,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
|||||||
|
|
||||||
bool linkDwarf(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
|
bool linkDwarf(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
|
||||||
const DebugMap &DM, LinkOptions Options) {
|
const DebugMap &DM, LinkOptions Options) {
|
||||||
DwarfLinker Linker(OutFile, BinHolder, std::move(Options));
|
DwarfLinkerForBinary Linker(OutFile, BinHolder, std::move(Options));
|
||||||
return Linker.link(DM);
|
return Linker.link(DM);
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
//===- tools/dsymutil/DwarfLinker.h - Dwarf debug info linker ---*- C++ -*-===//
|
//===- tools/dsymutil/DwarfLinkerForBinary.h --------------------*- 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.
|
||||||
@ -10,33 +10,17 @@
|
|||||||
#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/DWARFLinker/DWARFLinker.h"
|
||||||
|
#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
|
||||||
|
#include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.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.
|
||||||
@ -53,10 +37,10 @@ using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
|
|||||||
/// a function, the location for a variable). These relocations are
|
/// a function, the location for a variable). These relocations are
|
||||||
/// called ValidRelocs in the DwarfLinker and are gathered as a very
|
/// called ValidRelocs in the DwarfLinker and are gathered as a very
|
||||||
/// first step when we start processing a DebugMapObject.
|
/// first step when we start processing a DebugMapObject.
|
||||||
class DwarfLinker {
|
class DwarfLinkerForBinary {
|
||||||
public:
|
public:
|
||||||
DwarfLinker(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
|
DwarfLinkerForBinary(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
|
||||||
LinkOptions Options)
|
LinkOptions Options)
|
||||||
: OutFile(OutFile), BinHolder(BinHolder), Options(std::move(Options)) {}
|
: OutFile(OutFile), BinHolder(BinHolder), Options(std::move(Options)) {}
|
||||||
|
|
||||||
/// Link the contents of the DebugMap.
|
/// Link the contents of the DebugMap.
|
||||||
@ -74,6 +58,7 @@ public:
|
|||||||
TF_ODR = 1 << 4, ///< Use the ODR while keeping dependents.
|
TF_ODR = 1 << 4, ///< Use the ODR while keeping dependents.
|
||||||
TF_SkipPC = 1 << 5, ///< Skip all location attributes.
|
TF_SkipPC = 1 << 5, ///< Skip all location attributes.
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Remembers the oldest and newest DWARF version we've seen in a unit.
|
/// Remembers the oldest and newest DWARF version we've seen in a unit.
|
||||||
void updateDwarfVersion(unsigned Version) {
|
void updateDwarfVersion(unsigned Version) {
|
||||||
@ -89,7 +74,7 @@ private:
|
|||||||
OffsetsStringPool &StringPool);
|
OffsetsStringPool &StringPool);
|
||||||
|
|
||||||
/// Keeps track of relocations.
|
/// Keeps track of relocations.
|
||||||
class RelocationManager {
|
class RelocationManager : public AddressesMap {
|
||||||
struct ValidReloc {
|
struct ValidReloc {
|
||||||
uint64_t Offset;
|
uint64_t Offset;
|
||||||
uint32_t Size;
|
uint32_t Size;
|
||||||
@ -105,7 +90,7 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const DwarfLinker &Linker;
|
const DwarfLinkerForBinary &Linker;
|
||||||
|
|
||||||
/// The valid relocations for the current DebugMapObject.
|
/// The valid relocations for the current DebugMapObject.
|
||||||
/// This vector is sorted by relocation offset.
|
/// This vector is sorted by relocation offset.
|
||||||
@ -117,13 +102,48 @@ 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) : Linker(Linker) {}
|
RelocationManager(DwarfLinkerForBinary &Linker,
|
||||||
|
const object::ObjectFile &Obj, const DebugMapObject &DMO)
|
||||||
|
: Linker(Linker) {
|
||||||
|
findValidRelocsInDebugInfo(Obj, DMO);
|
||||||
|
|
||||||
bool hasValidRelocs() const { return !ValidRelocs.empty(); }
|
// 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(); }
|
||||||
|
|
||||||
/// Reset the NextValidReloc counter.
|
virtual bool areRelocationsResolved() const override { return true; }
|
||||||
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
|
||||||
@ -141,32 +161,44 @@ private:
|
|||||||
const DebugMapObject &DMO);
|
const DebugMapObject &DMO);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
bool hasValidRelocation(uint64_t StartOffset, uint64_t EndOffset,
|
bool hasValidRelocationAt(uint64_t StartOffset, uint64_t EndOffset,
|
||||||
CompileUnit::DIEInfo &Info);
|
CompileUnit::DIEInfo &Info) override;
|
||||||
|
|
||||||
bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
|
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.
|
/// Keeps track of data associated with one object during linking.
|
||||||
struct LinkContext {
|
struct LinkContext {
|
||||||
|
DwarfLinkerForBinary &Linker;
|
||||||
DebugMapObject &DMO;
|
DebugMapObject &DMO;
|
||||||
const object::ObjectFile *ObjectFile;
|
const object::ObjectFile *ObjectFile = nullptr;
|
||||||
RelocationManager RelocMgr;
|
std::unique_ptr<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, DwarfLinkerForBinary &Linker,
|
||||||
: DMO(DMO), RelocMgr(Linker) {
|
DebugMapObject &DMO)
|
||||||
|
: Linker(Linker), DMO(DMO) {
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
auto ErrOrObj = Linker.loadObject(DMO, Map);
|
if (auto ErrOrObj = Linker.loadObject(DMO, Map)) {
|
||||||
ObjectFile = ErrOrObj ? &*ErrOrObj : nullptr;
|
ObjectFile = &*ErrOrObj;
|
||||||
DwarfContext = ObjectFile ? DWARFContext::create(*ObjectFile) : nullptr;
|
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
|
/// Clear part of the context that's no longer needed when we're done with
|
||||||
@ -175,6 +207,7 @@ private:
|
|||||||
DwarfContext.reset(nullptr);
|
DwarfContext.reset(nullptr);
|
||||||
CompileUnits.clear();
|
CompileUnits.clear();
|
||||||
Ranges.clear();
|
Ranges.clear();
|
||||||
|
RelocMgr->clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -224,7 +257,6 @@ private:
|
|||||||
unsigned &UnitID, bool IsLittleEndian,
|
unsigned &UnitID, bool IsLittleEndian,
|
||||||
unsigned Indent = 0, bool Quiet = false);
|
unsigned Indent = 0, bool Quiet = false);
|
||||||
|
|
||||||
|
|
||||||
/// Mark the passed DIE as well as all the ones it depends on as kept.
|
/// Mark the passed DIE as well as all the ones it depends on as kept.
|
||||||
void keepDIEAndDependencies(RelocationManager &RelocMgr, RangesTy &Ranges,
|
void keepDIEAndDependencies(RelocationManager &RelocMgr, RangesTy &Ranges,
|
||||||
const UnitListTy &Units, const DWARFDie &DIE,
|
const UnitListTy &Units, const DWARFDie &DIE,
|
||||||
@ -258,7 +290,7 @@ private:
|
|||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
class DIECloner {
|
class DIECloner {
|
||||||
DwarfLinker &Linker;
|
DwarfLinkerForBinary &Linker;
|
||||||
RelocationManager &RelocMgr;
|
RelocationManager &RelocMgr;
|
||||||
|
|
||||||
/// Allocator used for all the DIEValue objects.
|
/// Allocator used for all the DIEValue objects.
|
||||||
@ -268,7 +300,7 @@ private:
|
|||||||
LinkOptions Options;
|
LinkOptions Options;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DIECloner(DwarfLinker &Linker, RelocationManager &RelocMgr,
|
DIECloner(DwarfLinkerForBinary &Linker, RelocationManager &RelocMgr,
|
||||||
BumpPtrAllocator &DIEAlloc,
|
BumpPtrAllocator &DIEAlloc,
|
||||||
std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
|
std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
|
||||||
LinkOptions &Options)
|
LinkOptions &Options)
|
||||||
@ -409,7 +441,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Assign an abbreviation number to \p Abbrev
|
/// Assign an abbreviation number to \p Abbrev
|
||||||
void AssignAbbrev(DIEAbbrev &Abbrev);
|
void assignAbbrev(DIEAbbrev &Abbrev);
|
||||||
|
|
||||||
/// Compute and emit debug_ranges section for \p Unit, and
|
/// Compute and emit debug_ranges section for \p Unit, and
|
||||||
/// patch the attributes referencing it.
|
/// patch the attributes referencing it.
|
@ -7,10 +7,10 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#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/DWARFLinker/DWARFLinkerCompileUnit.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/MC/MCTargetOptions.h"
|
#include "llvm/MC/MCTargetOptions.h"
|
||||||
#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
|
#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
|
||||||
|
@ -9,12 +9,12 @@
|
|||||||
#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"
|
||||||
#include "llvm/CodeGen/AsmPrinter.h"
|
#include "llvm/CodeGen/AsmPrinter.h"
|
||||||
#include "llvm/CodeGen/NonRelocatableStringpool.h"
|
#include "llvm/CodeGen/NonRelocatableStringpool.h"
|
||||||
|
#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.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/MC/MCAsmBackend.h"
|
#include "llvm/MC/MCAsmBackend.h"
|
||||||
|
@ -18,4 +18,4 @@
|
|||||||
type = Tool
|
type = Tool
|
||||||
name = dsymutil
|
name = dsymutil
|
||||||
parent = Tools
|
parent = Tools
|
||||||
required_libraries = AsmPrinter DebugInfoDWARF MC Object CodeGen Support all-targets
|
required_libraries = AsmPrinter DebugInfoDWARF DWARFLinker MC Object CodeGen Support all-targets
|
||||||
|
Loading…
Reference in New Issue
Block a user