1*9880d681SAndroid Build Coastguard Worker //===- tools/dsymutil/DwarfLinker.cpp - Dwarf debug info linker -----------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Linker
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker #include "DebugMap.h"
10*9880d681SAndroid Build Coastguard Worker #include "BinaryHolder.h"
11*9880d681SAndroid Build Coastguard Worker #include "DebugMap.h"
12*9880d681SAndroid Build Coastguard Worker #include "dsymutil.h"
13*9880d681SAndroid Build Coastguard Worker #include "MachOUtils.h"
14*9880d681SAndroid Build Coastguard Worker #include "NonRelocatableStringpool.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/IntervalMap.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringMap.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/AsmPrinter.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/DIE.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Config/config.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFContext.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmBackend.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCCodeEmitter.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCDwarf.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectFileInfo.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCTargetOptionsCommandFlags.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/MachO.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Dwarf.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/LEB128.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h"
41*9880d681SAndroid Build Coastguard Worker #include <string>
42*9880d681SAndroid Build Coastguard Worker #include <tuple>
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker namespace llvm {
45*9880d681SAndroid Build Coastguard Worker namespace dsymutil {
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker namespace {
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker template <typename KeyT, typename ValT>
50*9880d681SAndroid Build Coastguard Worker using HalfOpenIntervalMap =
51*9880d681SAndroid Build Coastguard Worker IntervalMap<KeyT, ValT, IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
52*9880d681SAndroid Build Coastguard Worker IntervalMapHalfOpenInfo<KeyT>>;
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker typedef HalfOpenIntervalMap<uint64_t, int64_t> FunctionIntervals;
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker // FIXME: Delete this structure.
57*9880d681SAndroid Build Coastguard Worker struct PatchLocation {
58*9880d681SAndroid Build Coastguard Worker DIE::value_iterator I;
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker PatchLocation() = default;
PatchLocationllvm::dsymutil::__anon73f354850111::PatchLocation61*9880d681SAndroid Build Coastguard Worker PatchLocation(DIE::value_iterator I) : I(I) {}
62*9880d681SAndroid Build Coastguard Worker
setllvm::dsymutil::__anon73f354850111::PatchLocation63*9880d681SAndroid Build Coastguard Worker void set(uint64_t New) const {
64*9880d681SAndroid Build Coastguard Worker assert(I);
65*9880d681SAndroid Build Coastguard Worker const auto &Old = *I;
66*9880d681SAndroid Build Coastguard Worker assert(Old.getType() == DIEValue::isInteger);
67*9880d681SAndroid Build Coastguard Worker *I = DIEValue(Old.getAttribute(), Old.getForm(), DIEInteger(New));
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker
getllvm::dsymutil::__anon73f354850111::PatchLocation70*9880d681SAndroid Build Coastguard Worker uint64_t get() const {
71*9880d681SAndroid Build Coastguard Worker assert(I);
72*9880d681SAndroid Build Coastguard Worker return I->getDIEInteger().getValue();
73*9880d681SAndroid Build Coastguard Worker }
74*9880d681SAndroid Build Coastguard Worker };
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker class CompileUnit;
77*9880d681SAndroid Build Coastguard Worker struct DeclMapInfo;
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker /// A DeclContext is a named program scope that is used for ODR
80*9880d681SAndroid Build Coastguard Worker /// uniquing of types.
81*9880d681SAndroid Build Coastguard Worker /// The set of DeclContext for the ODR-subject parts of a Dwarf link
82*9880d681SAndroid Build Coastguard Worker /// is expanded (and uniqued) with each new object file processed. We
83*9880d681SAndroid Build Coastguard Worker /// need to determine the context of each DIE in an linked object file
84*9880d681SAndroid Build Coastguard Worker /// to see if the corresponding type has already been emitted.
85*9880d681SAndroid Build Coastguard Worker ///
86*9880d681SAndroid Build Coastguard Worker /// The contexts are conceptually organised as a tree (eg. a function
87*9880d681SAndroid Build Coastguard Worker /// scope is contained in a namespace scope that contains other
88*9880d681SAndroid Build Coastguard Worker /// scopes), but storing/accessing them in an actual tree is too
89*9880d681SAndroid Build Coastguard Worker /// inefficient: we need to be able to very quickly query a context
90*9880d681SAndroid Build Coastguard Worker /// for a given child context by name. Storing a StringMap in each
91*9880d681SAndroid Build Coastguard Worker /// DeclContext would be too space inefficient.
92*9880d681SAndroid Build Coastguard Worker /// The solution here is to give each DeclContext a link to its parent
93*9880d681SAndroid Build Coastguard Worker /// (this allows to walk up the tree), but to query the existance of a
94*9880d681SAndroid Build Coastguard Worker /// specific DeclContext using a separate DenseMap keyed on the hash
95*9880d681SAndroid Build Coastguard Worker /// of the fully qualified name of the context.
96*9880d681SAndroid Build Coastguard Worker class DeclContext {
97*9880d681SAndroid Build Coastguard Worker unsigned QualifiedNameHash;
98*9880d681SAndroid Build Coastguard Worker uint32_t Line;
99*9880d681SAndroid Build Coastguard Worker uint32_t ByteSize;
100*9880d681SAndroid Build Coastguard Worker uint16_t Tag;
101*9880d681SAndroid Build Coastguard Worker StringRef Name;
102*9880d681SAndroid Build Coastguard Worker StringRef File;
103*9880d681SAndroid Build Coastguard Worker const DeclContext &Parent;
104*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal *LastSeenDIE;
105*9880d681SAndroid Build Coastguard Worker uint32_t LastSeenCompileUnitID;
106*9880d681SAndroid Build Coastguard Worker uint32_t CanonicalDIEOffset;
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker friend DeclMapInfo;
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Worker public:
111*9880d681SAndroid Build Coastguard Worker typedef DenseSet<DeclContext *, DeclMapInfo> Map;
112*9880d681SAndroid Build Coastguard Worker
DeclContext()113*9880d681SAndroid Build Coastguard Worker DeclContext()
114*9880d681SAndroid Build Coastguard Worker : QualifiedNameHash(0), Line(0), ByteSize(0),
115*9880d681SAndroid Build Coastguard Worker Tag(dwarf::DW_TAG_compile_unit), Name(), File(), Parent(*this),
116*9880d681SAndroid Build Coastguard Worker LastSeenDIE(nullptr), LastSeenCompileUnitID(0), CanonicalDIEOffset(0) {}
117*9880d681SAndroid Build Coastguard Worker
DeclContext(unsigned Hash,uint32_t Line,uint32_t ByteSize,uint16_t Tag,StringRef Name,StringRef File,const DeclContext & Parent,const DWARFDebugInfoEntryMinimal * LastSeenDIE=nullptr,unsigned CUId=0)118*9880d681SAndroid Build Coastguard Worker DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag,
119*9880d681SAndroid Build Coastguard Worker StringRef Name, StringRef File, const DeclContext &Parent,
120*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal *LastSeenDIE = nullptr,
121*9880d681SAndroid Build Coastguard Worker unsigned CUId = 0)
122*9880d681SAndroid Build Coastguard Worker : QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag),
123*9880d681SAndroid Build Coastguard Worker Name(Name), File(File), Parent(Parent), LastSeenDIE(LastSeenDIE),
124*9880d681SAndroid Build Coastguard Worker LastSeenCompileUnitID(CUId), CanonicalDIEOffset(0) {}
125*9880d681SAndroid Build Coastguard Worker
getQualifiedNameHash() const126*9880d681SAndroid Build Coastguard Worker uint32_t getQualifiedNameHash() const { return QualifiedNameHash; }
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker bool setLastSeenDIE(CompileUnit &U, const DWARFDebugInfoEntryMinimal *Die);
129*9880d681SAndroid Build Coastguard Worker
getCanonicalDIEOffset() const130*9880d681SAndroid Build Coastguard Worker uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; }
setCanonicalDIEOffset(uint32_t Offset)131*9880d681SAndroid Build Coastguard Worker void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; }
132*9880d681SAndroid Build Coastguard Worker
getTag() const133*9880d681SAndroid Build Coastguard Worker uint16_t getTag() const { return Tag; }
getName() const134*9880d681SAndroid Build Coastguard Worker StringRef getName() const { return Name; }
135*9880d681SAndroid Build Coastguard Worker };
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker /// Info type for the DenseMap storing the DeclContext pointers.
138*9880d681SAndroid Build Coastguard Worker struct DeclMapInfo : private DenseMapInfo<DeclContext *> {
139*9880d681SAndroid Build Coastguard Worker using DenseMapInfo<DeclContext *>::getEmptyKey;
140*9880d681SAndroid Build Coastguard Worker using DenseMapInfo<DeclContext *>::getTombstoneKey;
141*9880d681SAndroid Build Coastguard Worker
getHashValuellvm::dsymutil::__anon73f354850111::DeclMapInfo142*9880d681SAndroid Build Coastguard Worker static unsigned getHashValue(const DeclContext *Ctxt) {
143*9880d681SAndroid Build Coastguard Worker return Ctxt->QualifiedNameHash;
144*9880d681SAndroid Build Coastguard Worker }
145*9880d681SAndroid Build Coastguard Worker
isEqualllvm::dsymutil::__anon73f354850111::DeclMapInfo146*9880d681SAndroid Build Coastguard Worker static bool isEqual(const DeclContext *LHS, const DeclContext *RHS) {
147*9880d681SAndroid Build Coastguard Worker if (RHS == getEmptyKey() || RHS == getTombstoneKey())
148*9880d681SAndroid Build Coastguard Worker return RHS == LHS;
149*9880d681SAndroid Build Coastguard Worker return LHS->QualifiedNameHash == RHS->QualifiedNameHash &&
150*9880d681SAndroid Build Coastguard Worker LHS->Line == RHS->Line && LHS->ByteSize == RHS->ByteSize &&
151*9880d681SAndroid Build Coastguard Worker LHS->Name.data() == RHS->Name.data() &&
152*9880d681SAndroid Build Coastguard Worker LHS->File.data() == RHS->File.data() &&
153*9880d681SAndroid Build Coastguard Worker LHS->Parent.QualifiedNameHash == RHS->Parent.QualifiedNameHash;
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker };
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker /// This class gives a tree-like API to the DenseMap that stores the
158*9880d681SAndroid Build Coastguard Worker /// DeclContext objects. It also holds the BumpPtrAllocator where
159*9880d681SAndroid Build Coastguard Worker /// these objects will be allocated.
160*9880d681SAndroid Build Coastguard Worker class DeclContextTree {
161*9880d681SAndroid Build Coastguard Worker BumpPtrAllocator Allocator;
162*9880d681SAndroid Build Coastguard Worker DeclContext Root;
163*9880d681SAndroid Build Coastguard Worker DeclContext::Map Contexts;
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker public:
166*9880d681SAndroid Build Coastguard Worker /// Get the child of \a Context described by \a DIE in \a Unit. The
167*9880d681SAndroid Build Coastguard Worker /// required strings will be interned in \a StringPool.
168*9880d681SAndroid Build Coastguard Worker /// \returns The child DeclContext along with one bit that is set if
169*9880d681SAndroid Build Coastguard Worker /// this context is invalid.
170*9880d681SAndroid Build Coastguard Worker /// An invalid context means it shouldn't be considered for uniquing, but its
171*9880d681SAndroid Build Coastguard Worker /// not returning null, because some children of that context might be
172*9880d681SAndroid Build Coastguard Worker /// uniquing candidates. FIXME: The invalid bit along the return value is to
173*9880d681SAndroid Build Coastguard Worker /// emulate some dsymutil-classic functionality.
174*9880d681SAndroid Build Coastguard Worker PointerIntPair<DeclContext *, 1>
175*9880d681SAndroid Build Coastguard Worker getChildDeclContext(DeclContext &Context,
176*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal *DIE, CompileUnit &Unit,
177*9880d681SAndroid Build Coastguard Worker NonRelocatableStringpool &StringPool, bool InClangModule);
178*9880d681SAndroid Build Coastguard Worker
getRoot()179*9880d681SAndroid Build Coastguard Worker DeclContext &getRoot() { return Root; }
180*9880d681SAndroid Build Coastguard Worker };
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Worker /// \brief Stores all information relating to a compile unit, be it in
183*9880d681SAndroid Build Coastguard Worker /// its original instance in the object file to its brand new cloned
184*9880d681SAndroid Build Coastguard Worker /// and linked DIE tree.
185*9880d681SAndroid Build Coastguard Worker class CompileUnit {
186*9880d681SAndroid Build Coastguard Worker public:
187*9880d681SAndroid Build Coastguard Worker /// \brief Information gathered about a DIE in the object file.
188*9880d681SAndroid Build Coastguard Worker struct DIEInfo {
189*9880d681SAndroid Build Coastguard Worker int64_t AddrAdjust; ///< Address offset to apply to the described entity.
190*9880d681SAndroid Build Coastguard Worker DeclContext *Ctxt; ///< ODR Declaration context.
191*9880d681SAndroid Build Coastguard Worker DIE *Clone; ///< Cloned version of that DIE.
192*9880d681SAndroid Build Coastguard Worker uint32_t ParentIdx; ///< The index of this DIE's parent.
193*9880d681SAndroid Build Coastguard Worker bool Keep : 1; ///< Is the DIE part of the linked output?
194*9880d681SAndroid Build Coastguard Worker bool InDebugMap : 1;///< Was this DIE's entity found in the map?
195*9880d681SAndroid Build Coastguard Worker bool Prune : 1; ///< Is this a pure forward declaration we can strip?
196*9880d681SAndroid Build Coastguard Worker };
197*9880d681SAndroid Build Coastguard Worker
CompileUnit(DWARFUnit & OrigUnit,unsigned ID,bool CanUseODR,StringRef ClangModuleName)198*9880d681SAndroid Build Coastguard Worker CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR,
199*9880d681SAndroid Build Coastguard Worker StringRef ClangModuleName)
200*9880d681SAndroid Build Coastguard Worker : OrigUnit(OrigUnit), ID(ID), LowPc(UINT64_MAX), HighPc(0), RangeAlloc(),
201*9880d681SAndroid Build Coastguard Worker Ranges(RangeAlloc), ClangModuleName(ClangModuleName) {
202*9880d681SAndroid Build Coastguard Worker Info.resize(OrigUnit.getNumDIEs());
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Worker const auto *CUDie = OrigUnit.getUnitDIE(false);
205*9880d681SAndroid Build Coastguard Worker unsigned Lang = CUDie->getAttributeValueAsUnsignedConstant(
206*9880d681SAndroid Build Coastguard Worker &OrigUnit, dwarf::DW_AT_language, 0);
207*9880d681SAndroid Build Coastguard Worker HasODR = CanUseODR && (Lang == dwarf::DW_LANG_C_plus_plus ||
208*9880d681SAndroid Build Coastguard Worker Lang == dwarf::DW_LANG_C_plus_plus_03 ||
209*9880d681SAndroid Build Coastguard Worker Lang == dwarf::DW_LANG_C_plus_plus_11 ||
210*9880d681SAndroid Build Coastguard Worker Lang == dwarf::DW_LANG_C_plus_plus_14 ||
211*9880d681SAndroid Build Coastguard Worker Lang == dwarf::DW_LANG_ObjC_plus_plus);
212*9880d681SAndroid Build Coastguard Worker }
213*9880d681SAndroid Build Coastguard Worker
CompileUnit(CompileUnit && RHS)214*9880d681SAndroid Build Coastguard Worker CompileUnit(CompileUnit &&RHS)
215*9880d681SAndroid Build Coastguard Worker : OrigUnit(RHS.OrigUnit), Info(std::move(RHS.Info)),
216*9880d681SAndroid Build Coastguard Worker CUDie(std::move(RHS.CUDie)), StartOffset(RHS.StartOffset),
217*9880d681SAndroid Build Coastguard Worker NextUnitOffset(RHS.NextUnitOffset), RangeAlloc(), Ranges(RangeAlloc) {
218*9880d681SAndroid Build Coastguard Worker // The CompileUnit container has been 'reserve()'d with the right
219*9880d681SAndroid Build Coastguard Worker // size. We cannot move the IntervalMap anyway.
220*9880d681SAndroid Build Coastguard Worker llvm_unreachable("CompileUnits should not be moved.");
221*9880d681SAndroid Build Coastguard Worker }
222*9880d681SAndroid Build Coastguard Worker
getOrigUnit() const223*9880d681SAndroid Build Coastguard Worker DWARFUnit &getOrigUnit() const { return OrigUnit; }
224*9880d681SAndroid Build Coastguard Worker
getUniqueID() const225*9880d681SAndroid Build Coastguard Worker unsigned getUniqueID() const { return ID; }
226*9880d681SAndroid Build Coastguard Worker
getOutputUnitDIE() const227*9880d681SAndroid Build Coastguard Worker DIE *getOutputUnitDIE() const { return CUDie; }
setOutputUnitDIE(DIE * Die)228*9880d681SAndroid Build Coastguard Worker void setOutputUnitDIE(DIE *Die) { CUDie = Die; }
229*9880d681SAndroid Build Coastguard Worker
hasODR() const230*9880d681SAndroid Build Coastguard Worker bool hasODR() const { return HasODR; }
isClangModule() const231*9880d681SAndroid Build Coastguard Worker bool isClangModule() const { return !ClangModuleName.empty(); }
getClangModuleName() const232*9880d681SAndroid Build Coastguard Worker const std::string &getClangModuleName() const { return ClangModuleName; }
233*9880d681SAndroid Build Coastguard Worker
getInfo(unsigned Idx)234*9880d681SAndroid Build Coastguard Worker DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; }
getInfo(unsigned Idx) const235*9880d681SAndroid Build Coastguard Worker const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; }
236*9880d681SAndroid Build Coastguard Worker
getStartOffset() const237*9880d681SAndroid Build Coastguard Worker uint64_t getStartOffset() const { return StartOffset; }
getNextUnitOffset() const238*9880d681SAndroid Build Coastguard Worker uint64_t getNextUnitOffset() const { return NextUnitOffset; }
setStartOffset(uint64_t DebugInfoSize)239*9880d681SAndroid Build Coastguard Worker void setStartOffset(uint64_t DebugInfoSize) { StartOffset = DebugInfoSize; }
240*9880d681SAndroid Build Coastguard Worker
getLowPc() const241*9880d681SAndroid Build Coastguard Worker uint64_t getLowPc() const { return LowPc; }
getHighPc() const242*9880d681SAndroid Build Coastguard Worker uint64_t getHighPc() const { return HighPc; }
243*9880d681SAndroid Build Coastguard Worker
getUnitRangesAttribute() const244*9880d681SAndroid Build Coastguard Worker Optional<PatchLocation> getUnitRangesAttribute() const {
245*9880d681SAndroid Build Coastguard Worker return UnitRangeAttribute;
246*9880d681SAndroid Build Coastguard Worker }
getFunctionRanges() const247*9880d681SAndroid Build Coastguard Worker const FunctionIntervals &getFunctionRanges() const { return Ranges; }
getRangesAttributes() const248*9880d681SAndroid Build Coastguard Worker const std::vector<PatchLocation> &getRangesAttributes() const {
249*9880d681SAndroid Build Coastguard Worker return RangeAttributes;
250*9880d681SAndroid Build Coastguard Worker }
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker const std::vector<std::pair<PatchLocation, int64_t>> &
getLocationAttributes() const253*9880d681SAndroid Build Coastguard Worker getLocationAttributes() const {
254*9880d681SAndroid Build Coastguard Worker return LocationAttributes;
255*9880d681SAndroid Build Coastguard Worker }
256*9880d681SAndroid Build Coastguard Worker
setHasInterestingContent()257*9880d681SAndroid Build Coastguard Worker void setHasInterestingContent() { HasInterestingContent = true; }
hasInterestingContent()258*9880d681SAndroid Build Coastguard Worker bool hasInterestingContent() { return HasInterestingContent; }
259*9880d681SAndroid Build Coastguard Worker
260*9880d681SAndroid Build Coastguard Worker /// Mark every DIE in this unit as kept. This function also
261*9880d681SAndroid Build Coastguard Worker /// marks variables as InDebugMap so that they appear in the
262*9880d681SAndroid Build Coastguard Worker /// reconstructed accelerator tables.
263*9880d681SAndroid Build Coastguard Worker void markEverythingAsKept();
264*9880d681SAndroid Build Coastguard Worker
265*9880d681SAndroid Build Coastguard Worker /// \brief Compute the end offset for this unit. Must be
266*9880d681SAndroid Build Coastguard Worker /// called after the CU's DIEs have been cloned.
267*9880d681SAndroid Build Coastguard Worker /// \returns the next unit offset (which is also the current
268*9880d681SAndroid Build Coastguard Worker /// debug_info section size).
269*9880d681SAndroid Build Coastguard Worker uint64_t computeNextUnitOffset();
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker /// \brief Keep track of a forward reference to DIE \p Die in \p
272*9880d681SAndroid Build Coastguard Worker /// RefUnit by \p Attr. The attribute should be fixed up later to
273*9880d681SAndroid Build Coastguard Worker /// point to the absolute offset of \p Die in the debug_info section
274*9880d681SAndroid Build Coastguard Worker /// or to the canonical offset of \p Ctxt if it is non-null.
275*9880d681SAndroid Build Coastguard Worker void noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
276*9880d681SAndroid Build Coastguard Worker DeclContext *Ctxt, PatchLocation Attr);
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker /// \brief Apply all fixups recored by noteForwardReference().
279*9880d681SAndroid Build Coastguard Worker void fixupForwardReferences();
280*9880d681SAndroid Build Coastguard Worker
281*9880d681SAndroid Build Coastguard Worker /// \brief Add a function range [\p LowPC, \p HighPC) that is
282*9880d681SAndroid Build Coastguard Worker /// relocatad by applying offset \p PCOffset.
283*9880d681SAndroid Build Coastguard Worker void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Worker /// \brief Keep track of a DW_AT_range attribute that we will need to
286*9880d681SAndroid Build Coastguard Worker /// patch up later.
287*9880d681SAndroid Build Coastguard Worker void noteRangeAttribute(const DIE &Die, PatchLocation Attr);
288*9880d681SAndroid Build Coastguard Worker
289*9880d681SAndroid Build Coastguard Worker /// \brief Keep track of a location attribute pointing to a location
290*9880d681SAndroid Build Coastguard Worker /// list in the debug_loc section.
291*9880d681SAndroid Build Coastguard Worker void noteLocationAttribute(PatchLocation Attr, int64_t PcOffset);
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker /// \brief Add a name accelerator entry for \p Die with \p Name
294*9880d681SAndroid Build Coastguard Worker /// which is stored in the string table at \p Offset.
295*9880d681SAndroid Build Coastguard Worker void addNameAccelerator(const DIE *Die, const char *Name, uint32_t Offset,
296*9880d681SAndroid Build Coastguard Worker bool SkipPubnamesSection = false);
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker /// \brief Add a type accelerator entry for \p Die with \p Name
299*9880d681SAndroid Build Coastguard Worker /// which is stored in the string table at \p Offset.
300*9880d681SAndroid Build Coastguard Worker void addTypeAccelerator(const DIE *Die, const char *Name, uint32_t Offset);
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker struct AccelInfo {
303*9880d681SAndroid Build Coastguard Worker StringRef Name; ///< Name of the entry.
304*9880d681SAndroid Build Coastguard Worker const DIE *Die; ///< DIE this entry describes.
305*9880d681SAndroid Build Coastguard Worker uint32_t NameOffset; ///< Offset of Name in the string pool.
306*9880d681SAndroid Build Coastguard Worker bool SkipPubSection; ///< Emit this entry only in the apple_* sections.
307*9880d681SAndroid Build Coastguard Worker
AccelInfollvm::dsymutil::__anon73f354850111::CompileUnit::AccelInfo308*9880d681SAndroid Build Coastguard Worker AccelInfo(StringRef Name, const DIE *Die, uint32_t NameOffset,
309*9880d681SAndroid Build Coastguard Worker bool SkipPubSection = false)
310*9880d681SAndroid Build Coastguard Worker : Name(Name), Die(Die), NameOffset(NameOffset),
311*9880d681SAndroid Build Coastguard Worker SkipPubSection(SkipPubSection) {}
312*9880d681SAndroid Build Coastguard Worker };
313*9880d681SAndroid Build Coastguard Worker
getPubnames() const314*9880d681SAndroid Build Coastguard Worker const std::vector<AccelInfo> &getPubnames() const { return Pubnames; }
getPubtypes() const315*9880d681SAndroid Build Coastguard Worker const std::vector<AccelInfo> &getPubtypes() const { return Pubtypes; }
316*9880d681SAndroid Build Coastguard Worker
317*9880d681SAndroid Build Coastguard Worker /// Get the full path for file \a FileNum in the line table
getResolvedPath(unsigned FileNum)318*9880d681SAndroid Build Coastguard Worker StringRef getResolvedPath(unsigned FileNum) {
319*9880d681SAndroid Build Coastguard Worker if (FileNum >= ResolvedPaths.size())
320*9880d681SAndroid Build Coastguard Worker return StringRef();
321*9880d681SAndroid Build Coastguard Worker return ResolvedPaths[FileNum];
322*9880d681SAndroid Build Coastguard Worker }
323*9880d681SAndroid Build Coastguard Worker
324*9880d681SAndroid Build Coastguard Worker /// Set the fully resolved path for the line-table's file \a FileNum
325*9880d681SAndroid Build Coastguard Worker /// to \a Path.
setResolvedPath(unsigned FileNum,StringRef Path)326*9880d681SAndroid Build Coastguard Worker void setResolvedPath(unsigned FileNum, StringRef Path) {
327*9880d681SAndroid Build Coastguard Worker if (ResolvedPaths.size() <= FileNum)
328*9880d681SAndroid Build Coastguard Worker ResolvedPaths.resize(FileNum + 1);
329*9880d681SAndroid Build Coastguard Worker ResolvedPaths[FileNum] = Path;
330*9880d681SAndroid Build Coastguard Worker }
331*9880d681SAndroid Build Coastguard Worker
332*9880d681SAndroid Build Coastguard Worker private:
333*9880d681SAndroid Build Coastguard Worker DWARFUnit &OrigUnit;
334*9880d681SAndroid Build Coastguard Worker unsigned ID;
335*9880d681SAndroid Build Coastguard Worker std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index.
336*9880d681SAndroid Build Coastguard Worker DIE *CUDie; ///< Root of the linked DIE tree.
337*9880d681SAndroid Build Coastguard Worker
338*9880d681SAndroid Build Coastguard Worker uint64_t StartOffset;
339*9880d681SAndroid Build Coastguard Worker uint64_t NextUnitOffset;
340*9880d681SAndroid Build Coastguard Worker
341*9880d681SAndroid Build Coastguard Worker uint64_t LowPc;
342*9880d681SAndroid Build Coastguard Worker uint64_t HighPc;
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker /// \brief A list of attributes to fixup with the absolute offset of
345*9880d681SAndroid Build Coastguard Worker /// a DIE in the debug_info section.
346*9880d681SAndroid Build Coastguard Worker ///
347*9880d681SAndroid Build Coastguard Worker /// The offsets for the attributes in this array couldn't be set while
348*9880d681SAndroid Build Coastguard Worker /// cloning because for cross-cu forward refences the target DIE's
349*9880d681SAndroid Build Coastguard Worker /// offset isn't known you emit the reference attribute.
350*9880d681SAndroid Build Coastguard Worker std::vector<std::tuple<DIE *, const CompileUnit *, DeclContext *,
351*9880d681SAndroid Build Coastguard Worker PatchLocation>> ForwardDIEReferences;
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Worker FunctionIntervals::Allocator RangeAlloc;
354*9880d681SAndroid Build Coastguard Worker /// \brief The ranges in that interval map are the PC ranges for
355*9880d681SAndroid Build Coastguard Worker /// functions in this unit, associated with the PC offset to apply
356*9880d681SAndroid Build Coastguard Worker /// to the addresses to get the linked address.
357*9880d681SAndroid Build Coastguard Worker FunctionIntervals Ranges;
358*9880d681SAndroid Build Coastguard Worker
359*9880d681SAndroid Build Coastguard Worker /// \brief DW_AT_ranges attributes to patch after we have gathered
360*9880d681SAndroid Build Coastguard Worker /// all the unit's function addresses.
361*9880d681SAndroid Build Coastguard Worker /// @{
362*9880d681SAndroid Build Coastguard Worker std::vector<PatchLocation> RangeAttributes;
363*9880d681SAndroid Build Coastguard Worker Optional<PatchLocation> UnitRangeAttribute;
364*9880d681SAndroid Build Coastguard Worker /// @}
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker /// \brief Location attributes that need to be transfered from th
367*9880d681SAndroid Build Coastguard Worker /// original debug_loc section to the liked one. They are stored
368*9880d681SAndroid Build Coastguard Worker /// along with the PC offset that is to be applied to their
369*9880d681SAndroid Build Coastguard Worker /// function's address.
370*9880d681SAndroid Build Coastguard Worker std::vector<std::pair<PatchLocation, int64_t>> LocationAttributes;
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker /// \brief Accelerator entries for the unit, both for the pub*
373*9880d681SAndroid Build Coastguard Worker /// sections and the apple* ones.
374*9880d681SAndroid Build Coastguard Worker /// @{
375*9880d681SAndroid Build Coastguard Worker std::vector<AccelInfo> Pubnames;
376*9880d681SAndroid Build Coastguard Worker std::vector<AccelInfo> Pubtypes;
377*9880d681SAndroid Build Coastguard Worker /// @}
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Worker /// Cached resolved paths from the line table.
380*9880d681SAndroid Build Coastguard Worker /// Note, the StringRefs here point in to the intern (uniquing) string pool.
381*9880d681SAndroid Build Coastguard Worker /// This means that a StringRef returned here doesn't need to then be uniqued
382*9880d681SAndroid Build Coastguard Worker /// for the purposes of getting a unique address for each string.
383*9880d681SAndroid Build Coastguard Worker std::vector<StringRef> ResolvedPaths;
384*9880d681SAndroid Build Coastguard Worker
385*9880d681SAndroid Build Coastguard Worker /// Is this unit subject to the ODR rule?
386*9880d681SAndroid Build Coastguard Worker bool HasODR;
387*9880d681SAndroid Build Coastguard Worker /// Did a DIE actually contain a valid reloc?
388*9880d681SAndroid Build Coastguard Worker bool HasInterestingContent;
389*9880d681SAndroid Build Coastguard Worker /// If this is a Clang module, this holds the module's name.
390*9880d681SAndroid Build Coastguard Worker std::string ClangModuleName;
391*9880d681SAndroid Build Coastguard Worker };
392*9880d681SAndroid Build Coastguard Worker
markEverythingAsKept()393*9880d681SAndroid Build Coastguard Worker void CompileUnit::markEverythingAsKept() {
394*9880d681SAndroid Build Coastguard Worker for (auto &I : Info)
395*9880d681SAndroid Build Coastguard Worker // Mark everything that wasn't explicity marked for pruning.
396*9880d681SAndroid Build Coastguard Worker I.Keep = !I.Prune;
397*9880d681SAndroid Build Coastguard Worker }
398*9880d681SAndroid Build Coastguard Worker
computeNextUnitOffset()399*9880d681SAndroid Build Coastguard Worker uint64_t CompileUnit::computeNextUnitOffset() {
400*9880d681SAndroid Build Coastguard Worker NextUnitOffset = StartOffset + 11 /* Header size */;
401*9880d681SAndroid Build Coastguard Worker // The root DIE might be null, meaning that the Unit had nothing to
402*9880d681SAndroid Build Coastguard Worker // contribute to the linked output. In that case, we will emit the
403*9880d681SAndroid Build Coastguard Worker // unit header without any actual DIE.
404*9880d681SAndroid Build Coastguard Worker if (CUDie)
405*9880d681SAndroid Build Coastguard Worker NextUnitOffset += CUDie->getSize();
406*9880d681SAndroid Build Coastguard Worker return NextUnitOffset;
407*9880d681SAndroid Build Coastguard Worker }
408*9880d681SAndroid Build Coastguard Worker
409*9880d681SAndroid Build Coastguard Worker /// \brief Keep track of a forward cross-cu reference from this unit
410*9880d681SAndroid Build Coastguard Worker /// to \p Die that lives in \p RefUnit.
noteForwardReference(DIE * Die,const CompileUnit * RefUnit,DeclContext * Ctxt,PatchLocation Attr)411*9880d681SAndroid Build Coastguard Worker void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
412*9880d681SAndroid Build Coastguard Worker DeclContext *Ctxt, PatchLocation Attr) {
413*9880d681SAndroid Build Coastguard Worker ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr);
414*9880d681SAndroid Build Coastguard Worker }
415*9880d681SAndroid Build Coastguard Worker
416*9880d681SAndroid Build Coastguard Worker /// \brief Apply all fixups recorded by noteForwardReference().
fixupForwardReferences()417*9880d681SAndroid Build Coastguard Worker void CompileUnit::fixupForwardReferences() {
418*9880d681SAndroid Build Coastguard Worker for (const auto &Ref : ForwardDIEReferences) {
419*9880d681SAndroid Build Coastguard Worker DIE *RefDie;
420*9880d681SAndroid Build Coastguard Worker const CompileUnit *RefUnit;
421*9880d681SAndroid Build Coastguard Worker PatchLocation Attr;
422*9880d681SAndroid Build Coastguard Worker DeclContext *Ctxt;
423*9880d681SAndroid Build Coastguard Worker std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref;
424*9880d681SAndroid Build Coastguard Worker if (Ctxt && Ctxt->getCanonicalDIEOffset())
425*9880d681SAndroid Build Coastguard Worker Attr.set(Ctxt->getCanonicalDIEOffset());
426*9880d681SAndroid Build Coastguard Worker else
427*9880d681SAndroid Build Coastguard Worker Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());
428*9880d681SAndroid Build Coastguard Worker }
429*9880d681SAndroid Build Coastguard Worker }
430*9880d681SAndroid Build Coastguard Worker
addFunctionRange(uint64_t FuncLowPc,uint64_t FuncHighPc,int64_t PcOffset)431*9880d681SAndroid Build Coastguard Worker void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
432*9880d681SAndroid Build Coastguard Worker int64_t PcOffset) {
433*9880d681SAndroid Build Coastguard Worker Ranges.insert(FuncLowPc, FuncHighPc, PcOffset);
434*9880d681SAndroid Build Coastguard Worker this->LowPc = std::min(LowPc, FuncLowPc + PcOffset);
435*9880d681SAndroid Build Coastguard Worker this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
436*9880d681SAndroid Build Coastguard Worker }
437*9880d681SAndroid Build Coastguard Worker
noteRangeAttribute(const DIE & Die,PatchLocation Attr)438*9880d681SAndroid Build Coastguard Worker void CompileUnit::noteRangeAttribute(const DIE &Die, PatchLocation Attr) {
439*9880d681SAndroid Build Coastguard Worker if (Die.getTag() != dwarf::DW_TAG_compile_unit)
440*9880d681SAndroid Build Coastguard Worker RangeAttributes.push_back(Attr);
441*9880d681SAndroid Build Coastguard Worker else
442*9880d681SAndroid Build Coastguard Worker UnitRangeAttribute = Attr;
443*9880d681SAndroid Build Coastguard Worker }
444*9880d681SAndroid Build Coastguard Worker
noteLocationAttribute(PatchLocation Attr,int64_t PcOffset)445*9880d681SAndroid Build Coastguard Worker void CompileUnit::noteLocationAttribute(PatchLocation Attr, int64_t PcOffset) {
446*9880d681SAndroid Build Coastguard Worker LocationAttributes.emplace_back(Attr, PcOffset);
447*9880d681SAndroid Build Coastguard Worker }
448*9880d681SAndroid Build Coastguard Worker
449*9880d681SAndroid Build Coastguard Worker /// \brief Add a name accelerator entry for \p Die with \p Name
450*9880d681SAndroid Build Coastguard Worker /// which is stored in the string table at \p Offset.
addNameAccelerator(const DIE * Die,const char * Name,uint32_t Offset,bool SkipPubSection)451*9880d681SAndroid Build Coastguard Worker void CompileUnit::addNameAccelerator(const DIE *Die, const char *Name,
452*9880d681SAndroid Build Coastguard Worker uint32_t Offset, bool SkipPubSection) {
453*9880d681SAndroid Build Coastguard Worker Pubnames.emplace_back(Name, Die, Offset, SkipPubSection);
454*9880d681SAndroid Build Coastguard Worker }
455*9880d681SAndroid Build Coastguard Worker
456*9880d681SAndroid Build Coastguard Worker /// \brief Add a type accelerator entry for \p Die with \p Name
457*9880d681SAndroid Build Coastguard Worker /// which is stored in the string table at \p Offset.
addTypeAccelerator(const DIE * Die,const char * Name,uint32_t Offset)458*9880d681SAndroid Build Coastguard Worker void CompileUnit::addTypeAccelerator(const DIE *Die, const char *Name,
459*9880d681SAndroid Build Coastguard Worker uint32_t Offset) {
460*9880d681SAndroid Build Coastguard Worker Pubtypes.emplace_back(Name, Die, Offset, false);
461*9880d681SAndroid Build Coastguard Worker }
462*9880d681SAndroid Build Coastguard Worker
463*9880d681SAndroid Build Coastguard Worker /// \brief The Dwarf streaming logic
464*9880d681SAndroid Build Coastguard Worker ///
465*9880d681SAndroid Build Coastguard Worker /// All interactions with the MC layer that is used to build the debug
466*9880d681SAndroid Build Coastguard Worker /// information binary representation are handled in this class.
467*9880d681SAndroid Build Coastguard Worker class DwarfStreamer {
468*9880d681SAndroid Build Coastguard Worker /// \defgroup MCObjects MC layer objects constructed by the streamer
469*9880d681SAndroid Build Coastguard Worker /// @{
470*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCRegisterInfo> MRI;
471*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCAsmInfo> MAI;
472*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCObjectFileInfo> MOFI;
473*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCContext> MC;
474*9880d681SAndroid Build Coastguard Worker MCAsmBackend *MAB; // Owned by MCStreamer
475*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCInstrInfo> MII;
476*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCSubtargetInfo> MSTI;
477*9880d681SAndroid Build Coastguard Worker MCCodeEmitter *MCE; // Owned by MCStreamer
478*9880d681SAndroid Build Coastguard Worker MCStreamer *MS; // Owned by AsmPrinter
479*9880d681SAndroid Build Coastguard Worker std::unique_ptr<TargetMachine> TM;
480*9880d681SAndroid Build Coastguard Worker std::unique_ptr<AsmPrinter> Asm;
481*9880d681SAndroid Build Coastguard Worker /// @}
482*9880d681SAndroid Build Coastguard Worker
483*9880d681SAndroid Build Coastguard Worker /// \brief the file we stream the linked Dwarf to.
484*9880d681SAndroid Build Coastguard Worker std::unique_ptr<raw_fd_ostream> OutFile;
485*9880d681SAndroid Build Coastguard Worker
486*9880d681SAndroid Build Coastguard Worker uint32_t RangesSectionSize;
487*9880d681SAndroid Build Coastguard Worker uint32_t LocSectionSize;
488*9880d681SAndroid Build Coastguard Worker uint32_t LineSectionSize;
489*9880d681SAndroid Build Coastguard Worker uint32_t FrameSectionSize;
490*9880d681SAndroid Build Coastguard Worker
491*9880d681SAndroid Build Coastguard Worker /// \brief Emit the pubnames or pubtypes section contribution for \p
492*9880d681SAndroid Build Coastguard Worker /// Unit into \p Sec. The data is provided in \p Names.
493*9880d681SAndroid Build Coastguard Worker void emitPubSectionForUnit(MCSection *Sec, StringRef Name,
494*9880d681SAndroid Build Coastguard Worker const CompileUnit &Unit,
495*9880d681SAndroid Build Coastguard Worker const std::vector<CompileUnit::AccelInfo> &Names);
496*9880d681SAndroid Build Coastguard Worker
497*9880d681SAndroid Build Coastguard Worker public:
498*9880d681SAndroid Build Coastguard Worker /// \brief Actually create the streamer and the ouptut file.
499*9880d681SAndroid Build Coastguard Worker ///
500*9880d681SAndroid Build Coastguard Worker /// This could be done directly in the constructor, but it feels
501*9880d681SAndroid Build Coastguard Worker /// more natural to handle errors through return value.
502*9880d681SAndroid Build Coastguard Worker bool init(Triple TheTriple, StringRef OutputFilename);
503*9880d681SAndroid Build Coastguard Worker
504*9880d681SAndroid Build Coastguard Worker /// \brief Dump the file to the disk.
505*9880d681SAndroid Build Coastguard Worker bool finish(const DebugMap &);
506*9880d681SAndroid Build Coastguard Worker
getAsmPrinter() const507*9880d681SAndroid Build Coastguard Worker AsmPrinter &getAsmPrinter() const { return *Asm; }
508*9880d681SAndroid Build Coastguard Worker
509*9880d681SAndroid Build Coastguard Worker /// \brief Set the current output section to debug_info and change
510*9880d681SAndroid Build Coastguard Worker /// the MC Dwarf version to \p DwarfVersion.
511*9880d681SAndroid Build Coastguard Worker void switchToDebugInfoSection(unsigned DwarfVersion);
512*9880d681SAndroid Build Coastguard Worker
513*9880d681SAndroid Build Coastguard Worker /// \brief Emit the compilation unit header for \p Unit in the
514*9880d681SAndroid Build Coastguard Worker /// debug_info section.
515*9880d681SAndroid Build Coastguard Worker ///
516*9880d681SAndroid Build Coastguard Worker /// As a side effect, this also switches the current Dwarf version
517*9880d681SAndroid Build Coastguard Worker /// of the MC layer to the one of U.getOrigUnit().
518*9880d681SAndroid Build Coastguard Worker void emitCompileUnitHeader(CompileUnit &Unit);
519*9880d681SAndroid Build Coastguard Worker
520*9880d681SAndroid Build Coastguard Worker /// \brief Recursively emit the DIE tree rooted at \p Die.
521*9880d681SAndroid Build Coastguard Worker void emitDIE(DIE &Die);
522*9880d681SAndroid Build Coastguard Worker
523*9880d681SAndroid Build Coastguard Worker /// \brief Emit the abbreviation table \p Abbrevs to the
524*9880d681SAndroid Build Coastguard Worker /// debug_abbrev section.
525*9880d681SAndroid Build Coastguard Worker void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs);
526*9880d681SAndroid Build Coastguard Worker
527*9880d681SAndroid Build Coastguard Worker /// \brief Emit the string table described by \p Pool.
528*9880d681SAndroid Build Coastguard Worker void emitStrings(const NonRelocatableStringpool &Pool);
529*9880d681SAndroid Build Coastguard Worker
530*9880d681SAndroid Build Coastguard Worker /// \brief Emit debug_ranges for \p FuncRange by translating the
531*9880d681SAndroid Build Coastguard Worker /// original \p Entries.
532*9880d681SAndroid Build Coastguard Worker void emitRangesEntries(
533*9880d681SAndroid Build Coastguard Worker int64_t UnitPcOffset, uint64_t OrigLowPc,
534*9880d681SAndroid Build Coastguard Worker const FunctionIntervals::const_iterator &FuncRange,
535*9880d681SAndroid Build Coastguard Worker const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
536*9880d681SAndroid Build Coastguard Worker unsigned AddressSize);
537*9880d681SAndroid Build Coastguard Worker
538*9880d681SAndroid Build Coastguard Worker /// \brief Emit debug_aranges entries for \p Unit and if \p
539*9880d681SAndroid Build Coastguard Worker /// DoRangesSection is true, also emit the debug_ranges entries for
540*9880d681SAndroid Build Coastguard Worker /// the DW_TAG_compile_unit's DW_AT_ranges attribute.
541*9880d681SAndroid Build Coastguard Worker void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection);
542*9880d681SAndroid Build Coastguard Worker
getRangesSectionSize() const543*9880d681SAndroid Build Coastguard Worker uint32_t getRangesSectionSize() const { return RangesSectionSize; }
544*9880d681SAndroid Build Coastguard Worker
545*9880d681SAndroid Build Coastguard Worker /// \brief Emit the debug_loc contribution for \p Unit by copying
546*9880d681SAndroid Build Coastguard Worker /// the entries from \p Dwarf and offseting them. Update the
547*9880d681SAndroid Build Coastguard Worker /// location attributes to point to the new entries.
548*9880d681SAndroid Build Coastguard Worker void emitLocationsForUnit(const CompileUnit &Unit, DWARFContext &Dwarf);
549*9880d681SAndroid Build Coastguard Worker
550*9880d681SAndroid Build Coastguard Worker /// \brief Emit the line table described in \p Rows into the
551*9880d681SAndroid Build Coastguard Worker /// debug_line section.
552*9880d681SAndroid Build Coastguard Worker void emitLineTableForUnit(MCDwarfLineTableParams Params,
553*9880d681SAndroid Build Coastguard Worker StringRef PrologueBytes, unsigned MinInstLength,
554*9880d681SAndroid Build Coastguard Worker std::vector<DWARFDebugLine::Row> &Rows,
555*9880d681SAndroid Build Coastguard Worker unsigned AdddressSize);
556*9880d681SAndroid Build Coastguard Worker
getLineSectionSize() const557*9880d681SAndroid Build Coastguard Worker uint32_t getLineSectionSize() const { return LineSectionSize; }
558*9880d681SAndroid Build Coastguard Worker
559*9880d681SAndroid Build Coastguard Worker /// \brief Emit the .debug_pubnames contribution for \p Unit.
560*9880d681SAndroid Build Coastguard Worker void emitPubNamesForUnit(const CompileUnit &Unit);
561*9880d681SAndroid Build Coastguard Worker
562*9880d681SAndroid Build Coastguard Worker /// \brief Emit the .debug_pubtypes contribution for \p Unit.
563*9880d681SAndroid Build Coastguard Worker void emitPubTypesForUnit(const CompileUnit &Unit);
564*9880d681SAndroid Build Coastguard Worker
565*9880d681SAndroid Build Coastguard Worker /// \brief Emit a CIE.
566*9880d681SAndroid Build Coastguard Worker void emitCIE(StringRef CIEBytes);
567*9880d681SAndroid Build Coastguard Worker
568*9880d681SAndroid Build Coastguard Worker /// \brief Emit an FDE with data \p Bytes.
569*9880d681SAndroid Build Coastguard Worker void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address,
570*9880d681SAndroid Build Coastguard Worker StringRef Bytes);
571*9880d681SAndroid Build Coastguard Worker
getFrameSectionSize() const572*9880d681SAndroid Build Coastguard Worker uint32_t getFrameSectionSize() const { return FrameSectionSize; }
573*9880d681SAndroid Build Coastguard Worker };
574*9880d681SAndroid Build Coastguard Worker
init(Triple TheTriple,StringRef OutputFilename)575*9880d681SAndroid Build Coastguard Worker bool DwarfStreamer::init(Triple TheTriple, StringRef OutputFilename) {
576*9880d681SAndroid Build Coastguard Worker std::string ErrorStr;
577*9880d681SAndroid Build Coastguard Worker std::string TripleName;
578*9880d681SAndroid Build Coastguard Worker StringRef Context = "dwarf streamer init";
579*9880d681SAndroid Build Coastguard Worker
580*9880d681SAndroid Build Coastguard Worker // Get the target.
581*9880d681SAndroid Build Coastguard Worker const Target *TheTarget =
582*9880d681SAndroid Build Coastguard Worker TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);
583*9880d681SAndroid Build Coastguard Worker if (!TheTarget)
584*9880d681SAndroid Build Coastguard Worker return error(ErrorStr, Context);
585*9880d681SAndroid Build Coastguard Worker TripleName = TheTriple.getTriple();
586*9880d681SAndroid Build Coastguard Worker
587*9880d681SAndroid Build Coastguard Worker // Create all the MC Objects.
588*9880d681SAndroid Build Coastguard Worker MRI.reset(TheTarget->createMCRegInfo(TripleName));
589*9880d681SAndroid Build Coastguard Worker if (!MRI)
590*9880d681SAndroid Build Coastguard Worker return error(Twine("no register info for target ") + TripleName, Context);
591*9880d681SAndroid Build Coastguard Worker
592*9880d681SAndroid Build Coastguard Worker MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName));
593*9880d681SAndroid Build Coastguard Worker if (!MAI)
594*9880d681SAndroid Build Coastguard Worker return error("no asm info for target " + TripleName, Context);
595*9880d681SAndroid Build Coastguard Worker
596*9880d681SAndroid Build Coastguard Worker MOFI.reset(new MCObjectFileInfo);
597*9880d681SAndroid Build Coastguard Worker MC.reset(new MCContext(MAI.get(), MRI.get(), MOFI.get()));
598*9880d681SAndroid Build Coastguard Worker MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, CodeModel::Default, *MC);
599*9880d681SAndroid Build Coastguard Worker
600*9880d681SAndroid Build Coastguard Worker MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, "");
601*9880d681SAndroid Build Coastguard Worker if (!MAB)
602*9880d681SAndroid Build Coastguard Worker return error("no asm backend for target " + TripleName, Context);
603*9880d681SAndroid Build Coastguard Worker
604*9880d681SAndroid Build Coastguard Worker MII.reset(TheTarget->createMCInstrInfo());
605*9880d681SAndroid Build Coastguard Worker if (!MII)
606*9880d681SAndroid Build Coastguard Worker return error("no instr info info for target " + TripleName, Context);
607*9880d681SAndroid Build Coastguard Worker
608*9880d681SAndroid Build Coastguard Worker MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
609*9880d681SAndroid Build Coastguard Worker if (!MSTI)
610*9880d681SAndroid Build Coastguard Worker return error("no subtarget info for target " + TripleName, Context);
611*9880d681SAndroid Build Coastguard Worker
612*9880d681SAndroid Build Coastguard Worker MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MC);
613*9880d681SAndroid Build Coastguard Worker if (!MCE)
614*9880d681SAndroid Build Coastguard Worker return error("no code emitter for target " + TripleName, Context);
615*9880d681SAndroid Build Coastguard Worker
616*9880d681SAndroid Build Coastguard Worker // Create the output file.
617*9880d681SAndroid Build Coastguard Worker std::error_code EC;
618*9880d681SAndroid Build Coastguard Worker OutFile =
619*9880d681SAndroid Build Coastguard Worker llvm::make_unique<raw_fd_ostream>(OutputFilename, EC, sys::fs::F_None);
620*9880d681SAndroid Build Coastguard Worker if (EC)
621*9880d681SAndroid Build Coastguard Worker return error(Twine(OutputFilename) + ": " + EC.message(), Context);
622*9880d681SAndroid Build Coastguard Worker
623*9880d681SAndroid Build Coastguard Worker MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
624*9880d681SAndroid Build Coastguard Worker MS = TheTarget->createMCObjectStreamer(
625*9880d681SAndroid Build Coastguard Worker TheTriple, *MC, *MAB, *OutFile, MCE, *MSTI, MCOptions.MCRelaxAll,
626*9880d681SAndroid Build Coastguard Worker MCOptions.MCIncrementalLinkerCompatible,
627*9880d681SAndroid Build Coastguard Worker /*DWARFMustBeAtTheEnd*/ false);
628*9880d681SAndroid Build Coastguard Worker if (!MS)
629*9880d681SAndroid Build Coastguard Worker return error("no object streamer for target " + TripleName, Context);
630*9880d681SAndroid Build Coastguard Worker
631*9880d681SAndroid Build Coastguard Worker // Finally create the AsmPrinter we'll use to emit the DIEs.
632*9880d681SAndroid Build Coastguard Worker TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(),
633*9880d681SAndroid Build Coastguard Worker None));
634*9880d681SAndroid Build Coastguard Worker if (!TM)
635*9880d681SAndroid Build Coastguard Worker return error("no target machine for target " + TripleName, Context);
636*9880d681SAndroid Build Coastguard Worker
637*9880d681SAndroid Build Coastguard Worker Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
638*9880d681SAndroid Build Coastguard Worker if (!Asm)
639*9880d681SAndroid Build Coastguard Worker return error("no asm printer for target " + TripleName, Context);
640*9880d681SAndroid Build Coastguard Worker
641*9880d681SAndroid Build Coastguard Worker RangesSectionSize = 0;
642*9880d681SAndroid Build Coastguard Worker LocSectionSize = 0;
643*9880d681SAndroid Build Coastguard Worker LineSectionSize = 0;
644*9880d681SAndroid Build Coastguard Worker FrameSectionSize = 0;
645*9880d681SAndroid Build Coastguard Worker
646*9880d681SAndroid Build Coastguard Worker return true;
647*9880d681SAndroid Build Coastguard Worker }
648*9880d681SAndroid Build Coastguard Worker
finish(const DebugMap & DM)649*9880d681SAndroid Build Coastguard Worker bool DwarfStreamer::finish(const DebugMap &DM) {
650*9880d681SAndroid Build Coastguard Worker if (DM.getTriple().isOSDarwin() && !DM.getBinaryPath().empty())
651*9880d681SAndroid Build Coastguard Worker return MachOUtils::generateDsymCompanion(DM, *MS, *OutFile);
652*9880d681SAndroid Build Coastguard Worker
653*9880d681SAndroid Build Coastguard Worker MS->Finish();
654*9880d681SAndroid Build Coastguard Worker return true;
655*9880d681SAndroid Build Coastguard Worker }
656*9880d681SAndroid Build Coastguard Worker
657*9880d681SAndroid Build Coastguard Worker /// \brief Set the current output section to debug_info and change
658*9880d681SAndroid Build Coastguard Worker /// the MC Dwarf version to \p DwarfVersion.
switchToDebugInfoSection(unsigned DwarfVersion)659*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) {
660*9880d681SAndroid Build Coastguard Worker MS->SwitchSection(MOFI->getDwarfInfoSection());
661*9880d681SAndroid Build Coastguard Worker MC->setDwarfVersion(DwarfVersion);
662*9880d681SAndroid Build Coastguard Worker }
663*9880d681SAndroid Build Coastguard Worker
664*9880d681SAndroid Build Coastguard Worker /// \brief Emit the compilation unit header for \p Unit in the
665*9880d681SAndroid Build Coastguard Worker /// debug_info section.
666*9880d681SAndroid Build Coastguard Worker ///
667*9880d681SAndroid Build Coastguard Worker /// A Dwarf scetion header is encoded as:
668*9880d681SAndroid Build Coastguard Worker /// uint32_t Unit length (omiting this field)
669*9880d681SAndroid Build Coastguard Worker /// uint16_t Version
670*9880d681SAndroid Build Coastguard Worker /// uint32_t Abbreviation table offset
671*9880d681SAndroid Build Coastguard Worker /// uint8_t Address size
672*9880d681SAndroid Build Coastguard Worker ///
673*9880d681SAndroid Build Coastguard Worker /// Leading to a total of 11 bytes.
emitCompileUnitHeader(CompileUnit & Unit)674*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit) {
675*9880d681SAndroid Build Coastguard Worker unsigned Version = Unit.getOrigUnit().getVersion();
676*9880d681SAndroid Build Coastguard Worker switchToDebugInfoSection(Version);
677*9880d681SAndroid Build Coastguard Worker
678*9880d681SAndroid Build Coastguard Worker // Emit size of content not including length itself. The size has
679*9880d681SAndroid Build Coastguard Worker // already been computed in CompileUnit::computeOffsets(). Substract
680*9880d681SAndroid Build Coastguard Worker // 4 to that size to account for the length field.
681*9880d681SAndroid Build Coastguard Worker Asm->EmitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4);
682*9880d681SAndroid Build Coastguard Worker Asm->EmitInt16(Version);
683*9880d681SAndroid Build Coastguard Worker // We share one abbreviations table across all units so it's always at the
684*9880d681SAndroid Build Coastguard Worker // start of the section.
685*9880d681SAndroid Build Coastguard Worker Asm->EmitInt32(0);
686*9880d681SAndroid Build Coastguard Worker Asm->EmitInt8(Unit.getOrigUnit().getAddressByteSize());
687*9880d681SAndroid Build Coastguard Worker }
688*9880d681SAndroid Build Coastguard Worker
689*9880d681SAndroid Build Coastguard Worker /// \brief Emit the \p Abbrevs array as the shared abbreviation table
690*9880d681SAndroid Build Coastguard Worker /// for the linked Dwarf file.
emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> & Abbrevs)691*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitAbbrevs(
692*9880d681SAndroid Build Coastguard Worker const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs) {
693*9880d681SAndroid Build Coastguard Worker MS->SwitchSection(MOFI->getDwarfAbbrevSection());
694*9880d681SAndroid Build Coastguard Worker Asm->emitDwarfAbbrevs(Abbrevs);
695*9880d681SAndroid Build Coastguard Worker }
696*9880d681SAndroid Build Coastguard Worker
697*9880d681SAndroid Build Coastguard Worker /// \brief Recursively emit the DIE tree rooted at \p Die.
emitDIE(DIE & Die)698*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitDIE(DIE &Die) {
699*9880d681SAndroid Build Coastguard Worker MS->SwitchSection(MOFI->getDwarfInfoSection());
700*9880d681SAndroid Build Coastguard Worker Asm->emitDwarfDIE(Die);
701*9880d681SAndroid Build Coastguard Worker }
702*9880d681SAndroid Build Coastguard Worker
703*9880d681SAndroid Build Coastguard Worker /// \brief Emit the debug_str section stored in \p Pool.
emitStrings(const NonRelocatableStringpool & Pool)704*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) {
705*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->SwitchSection(MOFI->getDwarfStrSection());
706*9880d681SAndroid Build Coastguard Worker for (auto *Entry = Pool.getFirstEntry(); Entry;
707*9880d681SAndroid Build Coastguard Worker Entry = Pool.getNextEntry(Entry))
708*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitBytes(
709*9880d681SAndroid Build Coastguard Worker StringRef(Entry->getKey().data(), Entry->getKey().size() + 1));
710*9880d681SAndroid Build Coastguard Worker }
711*9880d681SAndroid Build Coastguard Worker
712*9880d681SAndroid Build Coastguard Worker /// \brief Emit the debug_range section contents for \p FuncRange by
713*9880d681SAndroid Build Coastguard Worker /// translating the original \p Entries. The debug_range section
714*9880d681SAndroid Build Coastguard Worker /// format is totally trivial, consisting just of pairs of address
715*9880d681SAndroid Build Coastguard Worker /// sized addresses describing the ranges.
emitRangesEntries(int64_t UnitPcOffset,uint64_t OrigLowPc,const FunctionIntervals::const_iterator & FuncRange,const std::vector<DWARFDebugRangeList::RangeListEntry> & Entries,unsigned AddressSize)716*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitRangesEntries(
717*9880d681SAndroid Build Coastguard Worker int64_t UnitPcOffset, uint64_t OrigLowPc,
718*9880d681SAndroid Build Coastguard Worker const FunctionIntervals::const_iterator &FuncRange,
719*9880d681SAndroid Build Coastguard Worker const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
720*9880d681SAndroid Build Coastguard Worker unsigned AddressSize) {
721*9880d681SAndroid Build Coastguard Worker MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
722*9880d681SAndroid Build Coastguard Worker
723*9880d681SAndroid Build Coastguard Worker // Offset each range by the right amount.
724*9880d681SAndroid Build Coastguard Worker int64_t PcOffset = Entries.empty() ? 0 : FuncRange.value() + UnitPcOffset;
725*9880d681SAndroid Build Coastguard Worker for (const auto &Range : Entries) {
726*9880d681SAndroid Build Coastguard Worker if (Range.isBaseAddressSelectionEntry(AddressSize)) {
727*9880d681SAndroid Build Coastguard Worker warn("unsupported base address selection operation",
728*9880d681SAndroid Build Coastguard Worker "emitting debug_ranges");
729*9880d681SAndroid Build Coastguard Worker break;
730*9880d681SAndroid Build Coastguard Worker }
731*9880d681SAndroid Build Coastguard Worker // Do not emit empty ranges.
732*9880d681SAndroid Build Coastguard Worker if (Range.StartAddress == Range.EndAddress)
733*9880d681SAndroid Build Coastguard Worker continue;
734*9880d681SAndroid Build Coastguard Worker
735*9880d681SAndroid Build Coastguard Worker // All range entries should lie in the function range.
736*9880d681SAndroid Build Coastguard Worker if (!(Range.StartAddress + OrigLowPc >= FuncRange.start() &&
737*9880d681SAndroid Build Coastguard Worker Range.EndAddress + OrigLowPc <= FuncRange.stop()))
738*9880d681SAndroid Build Coastguard Worker warn("inconsistent range data.", "emitting debug_ranges");
739*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(Range.StartAddress + PcOffset, AddressSize);
740*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(Range.EndAddress + PcOffset, AddressSize);
741*9880d681SAndroid Build Coastguard Worker RangesSectionSize += 2 * AddressSize;
742*9880d681SAndroid Build Coastguard Worker }
743*9880d681SAndroid Build Coastguard Worker
744*9880d681SAndroid Build Coastguard Worker // Add the terminator entry.
745*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(0, AddressSize);
746*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(0, AddressSize);
747*9880d681SAndroid Build Coastguard Worker RangesSectionSize += 2 * AddressSize;
748*9880d681SAndroid Build Coastguard Worker }
749*9880d681SAndroid Build Coastguard Worker
750*9880d681SAndroid Build Coastguard Worker /// \brief Emit the debug_aranges contribution of a unit and
751*9880d681SAndroid Build Coastguard Worker /// if \p DoDebugRanges is true the debug_range contents for a
752*9880d681SAndroid Build Coastguard Worker /// compile_unit level DW_AT_ranges attribute (Which are basically the
753*9880d681SAndroid Build Coastguard Worker /// same thing with a different base address).
754*9880d681SAndroid Build Coastguard Worker /// Just aggregate all the ranges gathered inside that unit.
emitUnitRangesEntries(CompileUnit & Unit,bool DoDebugRanges)755*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit,
756*9880d681SAndroid Build Coastguard Worker bool DoDebugRanges) {
757*9880d681SAndroid Build Coastguard Worker unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
758*9880d681SAndroid Build Coastguard Worker // Gather the ranges in a vector, so that we can simplify them. The
759*9880d681SAndroid Build Coastguard Worker // IntervalMap will have coalesced the non-linked ranges, but here
760*9880d681SAndroid Build Coastguard Worker // we want to coalesce the linked addresses.
761*9880d681SAndroid Build Coastguard Worker std::vector<std::pair<uint64_t, uint64_t>> Ranges;
762*9880d681SAndroid Build Coastguard Worker const auto &FunctionRanges = Unit.getFunctionRanges();
763*9880d681SAndroid Build Coastguard Worker for (auto Range = FunctionRanges.begin(), End = FunctionRanges.end();
764*9880d681SAndroid Build Coastguard Worker Range != End; ++Range)
765*9880d681SAndroid Build Coastguard Worker Ranges.push_back(std::make_pair(Range.start() + Range.value(),
766*9880d681SAndroid Build Coastguard Worker Range.stop() + Range.value()));
767*9880d681SAndroid Build Coastguard Worker
768*9880d681SAndroid Build Coastguard Worker // The object addresses where sorted, but again, the linked
769*9880d681SAndroid Build Coastguard Worker // addresses might end up in a different order.
770*9880d681SAndroid Build Coastguard Worker std::sort(Ranges.begin(), Ranges.end());
771*9880d681SAndroid Build Coastguard Worker
772*9880d681SAndroid Build Coastguard Worker if (!Ranges.empty()) {
773*9880d681SAndroid Build Coastguard Worker MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
774*9880d681SAndroid Build Coastguard Worker
775*9880d681SAndroid Build Coastguard Worker MCSymbol *BeginLabel = Asm->createTempSymbol("Barange");
776*9880d681SAndroid Build Coastguard Worker MCSymbol *EndLabel = Asm->createTempSymbol("Earange");
777*9880d681SAndroid Build Coastguard Worker
778*9880d681SAndroid Build Coastguard Worker unsigned HeaderSize =
779*9880d681SAndroid Build Coastguard Worker sizeof(int32_t) + // Size of contents (w/o this field
780*9880d681SAndroid Build Coastguard Worker sizeof(int16_t) + // DWARF ARange version number
781*9880d681SAndroid Build Coastguard Worker sizeof(int32_t) + // Offset of CU in the .debug_info section
782*9880d681SAndroid Build Coastguard Worker sizeof(int8_t) + // Pointer Size (in bytes)
783*9880d681SAndroid Build Coastguard Worker sizeof(int8_t); // Segment Size (in bytes)
784*9880d681SAndroid Build Coastguard Worker
785*9880d681SAndroid Build Coastguard Worker unsigned TupleSize = AddressSize * 2;
786*9880d681SAndroid Build Coastguard Worker unsigned Padding = OffsetToAlignment(HeaderSize, TupleSize);
787*9880d681SAndroid Build Coastguard Worker
788*9880d681SAndroid Build Coastguard Worker Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Arange length
789*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitLabel(BeginLabel);
790*9880d681SAndroid Build Coastguard Worker Asm->EmitInt16(dwarf::DW_ARANGES_VERSION); // Version number
791*9880d681SAndroid Build Coastguard Worker Asm->EmitInt32(Unit.getStartOffset()); // Corresponding unit's offset
792*9880d681SAndroid Build Coastguard Worker Asm->EmitInt8(AddressSize); // Address size
793*9880d681SAndroid Build Coastguard Worker Asm->EmitInt8(0); // Segment size
794*9880d681SAndroid Build Coastguard Worker
795*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->emitFill(Padding, 0x0);
796*9880d681SAndroid Build Coastguard Worker
797*9880d681SAndroid Build Coastguard Worker for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End;
798*9880d681SAndroid Build Coastguard Worker ++Range) {
799*9880d681SAndroid Build Coastguard Worker uint64_t RangeStart = Range->first;
800*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(RangeStart, AddressSize);
801*9880d681SAndroid Build Coastguard Worker while ((Range + 1) != End && Range->second == (Range + 1)->first)
802*9880d681SAndroid Build Coastguard Worker ++Range;
803*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(Range->second - RangeStart, AddressSize);
804*9880d681SAndroid Build Coastguard Worker }
805*9880d681SAndroid Build Coastguard Worker
806*9880d681SAndroid Build Coastguard Worker // Emit terminator
807*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitIntValue(0, AddressSize);
808*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitIntValue(0, AddressSize);
809*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitLabel(EndLabel);
810*9880d681SAndroid Build Coastguard Worker }
811*9880d681SAndroid Build Coastguard Worker
812*9880d681SAndroid Build Coastguard Worker if (!DoDebugRanges)
813*9880d681SAndroid Build Coastguard Worker return;
814*9880d681SAndroid Build Coastguard Worker
815*9880d681SAndroid Build Coastguard Worker MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
816*9880d681SAndroid Build Coastguard Worker // Offset each range by the right amount.
817*9880d681SAndroid Build Coastguard Worker int64_t PcOffset = -Unit.getLowPc();
818*9880d681SAndroid Build Coastguard Worker // Emit coalesced ranges.
819*9880d681SAndroid Build Coastguard Worker for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End; ++Range) {
820*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(Range->first + PcOffset, AddressSize);
821*9880d681SAndroid Build Coastguard Worker while (Range + 1 != End && Range->second == (Range + 1)->first)
822*9880d681SAndroid Build Coastguard Worker ++Range;
823*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(Range->second + PcOffset, AddressSize);
824*9880d681SAndroid Build Coastguard Worker RangesSectionSize += 2 * AddressSize;
825*9880d681SAndroid Build Coastguard Worker }
826*9880d681SAndroid Build Coastguard Worker
827*9880d681SAndroid Build Coastguard Worker // Add the terminator entry.
828*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(0, AddressSize);
829*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(0, AddressSize);
830*9880d681SAndroid Build Coastguard Worker RangesSectionSize += 2 * AddressSize;
831*9880d681SAndroid Build Coastguard Worker }
832*9880d681SAndroid Build Coastguard Worker
833*9880d681SAndroid Build Coastguard Worker /// \brief Emit location lists for \p Unit and update attribtues to
834*9880d681SAndroid Build Coastguard Worker /// point to the new entries.
emitLocationsForUnit(const CompileUnit & Unit,DWARFContext & Dwarf)835*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitLocationsForUnit(const CompileUnit &Unit,
836*9880d681SAndroid Build Coastguard Worker DWARFContext &Dwarf) {
837*9880d681SAndroid Build Coastguard Worker const auto &Attributes = Unit.getLocationAttributes();
838*9880d681SAndroid Build Coastguard Worker
839*9880d681SAndroid Build Coastguard Worker if (Attributes.empty())
840*9880d681SAndroid Build Coastguard Worker return;
841*9880d681SAndroid Build Coastguard Worker
842*9880d681SAndroid Build Coastguard Worker MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
843*9880d681SAndroid Build Coastguard Worker
844*9880d681SAndroid Build Coastguard Worker unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
845*9880d681SAndroid Build Coastguard Worker const DWARFSection &InputSec = Dwarf.getLocSection();
846*9880d681SAndroid Build Coastguard Worker DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
847*9880d681SAndroid Build Coastguard Worker DWARFUnit &OrigUnit = Unit.getOrigUnit();
848*9880d681SAndroid Build Coastguard Worker const auto *OrigUnitDie = OrigUnit.getUnitDIE(false);
849*9880d681SAndroid Build Coastguard Worker int64_t UnitPcOffset = 0;
850*9880d681SAndroid Build Coastguard Worker uint64_t OrigLowPc = OrigUnitDie->getAttributeValueAsAddress(
851*9880d681SAndroid Build Coastguard Worker &OrigUnit, dwarf::DW_AT_low_pc, -1ULL);
852*9880d681SAndroid Build Coastguard Worker if (OrigLowPc != -1ULL)
853*9880d681SAndroid Build Coastguard Worker UnitPcOffset = int64_t(OrigLowPc) - Unit.getLowPc();
854*9880d681SAndroid Build Coastguard Worker
855*9880d681SAndroid Build Coastguard Worker for (const auto &Attr : Attributes) {
856*9880d681SAndroid Build Coastguard Worker uint32_t Offset = Attr.first.get();
857*9880d681SAndroid Build Coastguard Worker Attr.first.set(LocSectionSize);
858*9880d681SAndroid Build Coastguard Worker // This is the quantity to add to the old location address to get
859*9880d681SAndroid Build Coastguard Worker // the correct address for the new one.
860*9880d681SAndroid Build Coastguard Worker int64_t LocPcOffset = Attr.second + UnitPcOffset;
861*9880d681SAndroid Build Coastguard Worker while (Data.isValidOffset(Offset)) {
862*9880d681SAndroid Build Coastguard Worker uint64_t Low = Data.getUnsigned(&Offset, AddressSize);
863*9880d681SAndroid Build Coastguard Worker uint64_t High = Data.getUnsigned(&Offset, AddressSize);
864*9880d681SAndroid Build Coastguard Worker LocSectionSize += 2 * AddressSize;
865*9880d681SAndroid Build Coastguard Worker if (Low == 0 && High == 0) {
866*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitIntValue(0, AddressSize);
867*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitIntValue(0, AddressSize);
868*9880d681SAndroid Build Coastguard Worker break;
869*9880d681SAndroid Build Coastguard Worker }
870*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitIntValue(Low + LocPcOffset, AddressSize);
871*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitIntValue(High + LocPcOffset, AddressSize);
872*9880d681SAndroid Build Coastguard Worker uint64_t Length = Data.getU16(&Offset);
873*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitIntValue(Length, 2);
874*9880d681SAndroid Build Coastguard Worker // Just copy the bytes over.
875*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitBytes(
876*9880d681SAndroid Build Coastguard Worker StringRef(InputSec.Data.substr(Offset, Length)));
877*9880d681SAndroid Build Coastguard Worker Offset += Length;
878*9880d681SAndroid Build Coastguard Worker LocSectionSize += Length + 2;
879*9880d681SAndroid Build Coastguard Worker }
880*9880d681SAndroid Build Coastguard Worker }
881*9880d681SAndroid Build Coastguard Worker }
882*9880d681SAndroid Build Coastguard Worker
emitLineTableForUnit(MCDwarfLineTableParams Params,StringRef PrologueBytes,unsigned MinInstLength,std::vector<DWARFDebugLine::Row> & Rows,unsigned PointerSize)883*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitLineTableForUnit(MCDwarfLineTableParams Params,
884*9880d681SAndroid Build Coastguard Worker StringRef PrologueBytes,
885*9880d681SAndroid Build Coastguard Worker unsigned MinInstLength,
886*9880d681SAndroid Build Coastguard Worker std::vector<DWARFDebugLine::Row> &Rows,
887*9880d681SAndroid Build Coastguard Worker unsigned PointerSize) {
888*9880d681SAndroid Build Coastguard Worker // Switch to the section where the table will be emitted into.
889*9880d681SAndroid Build Coastguard Worker MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection());
890*9880d681SAndroid Build Coastguard Worker MCSymbol *LineStartSym = MC->createTempSymbol();
891*9880d681SAndroid Build Coastguard Worker MCSymbol *LineEndSym = MC->createTempSymbol();
892*9880d681SAndroid Build Coastguard Worker
893*9880d681SAndroid Build Coastguard Worker // The first 4 bytes is the total length of the information for this
894*9880d681SAndroid Build Coastguard Worker // compilation unit (not including these 4 bytes for the length).
895*9880d681SAndroid Build Coastguard Worker Asm->EmitLabelDifference(LineEndSym, LineStartSym, 4);
896*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitLabel(LineStartSym);
897*9880d681SAndroid Build Coastguard Worker // Copy Prologue.
898*9880d681SAndroid Build Coastguard Worker MS->EmitBytes(PrologueBytes);
899*9880d681SAndroid Build Coastguard Worker LineSectionSize += PrologueBytes.size() + 4;
900*9880d681SAndroid Build Coastguard Worker
901*9880d681SAndroid Build Coastguard Worker SmallString<128> EncodingBuffer;
902*9880d681SAndroid Build Coastguard Worker raw_svector_ostream EncodingOS(EncodingBuffer);
903*9880d681SAndroid Build Coastguard Worker
904*9880d681SAndroid Build Coastguard Worker if (Rows.empty()) {
905*9880d681SAndroid Build Coastguard Worker // We only have the dummy entry, dsymutil emits an entry with a 0
906*9880d681SAndroid Build Coastguard Worker // address in that case.
907*9880d681SAndroid Build Coastguard Worker MCDwarfLineAddr::Encode(*MC, Params, INT64_MAX, 0, EncodingOS);
908*9880d681SAndroid Build Coastguard Worker MS->EmitBytes(EncodingOS.str());
909*9880d681SAndroid Build Coastguard Worker LineSectionSize += EncodingBuffer.size();
910*9880d681SAndroid Build Coastguard Worker MS->EmitLabel(LineEndSym);
911*9880d681SAndroid Build Coastguard Worker return;
912*9880d681SAndroid Build Coastguard Worker }
913*9880d681SAndroid Build Coastguard Worker
914*9880d681SAndroid Build Coastguard Worker // Line table state machine fields
915*9880d681SAndroid Build Coastguard Worker unsigned FileNum = 1;
916*9880d681SAndroid Build Coastguard Worker unsigned LastLine = 1;
917*9880d681SAndroid Build Coastguard Worker unsigned Column = 0;
918*9880d681SAndroid Build Coastguard Worker unsigned IsStatement = 1;
919*9880d681SAndroid Build Coastguard Worker unsigned Isa = 0;
920*9880d681SAndroid Build Coastguard Worker uint64_t Address = -1ULL;
921*9880d681SAndroid Build Coastguard Worker
922*9880d681SAndroid Build Coastguard Worker unsigned RowsSinceLastSequence = 0;
923*9880d681SAndroid Build Coastguard Worker
924*9880d681SAndroid Build Coastguard Worker for (unsigned Idx = 0; Idx < Rows.size(); ++Idx) {
925*9880d681SAndroid Build Coastguard Worker auto &Row = Rows[Idx];
926*9880d681SAndroid Build Coastguard Worker
927*9880d681SAndroid Build Coastguard Worker int64_t AddressDelta;
928*9880d681SAndroid Build Coastguard Worker if (Address == -1ULL) {
929*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(dwarf::DW_LNS_extended_op, 1);
930*9880d681SAndroid Build Coastguard Worker MS->EmitULEB128IntValue(PointerSize + 1);
931*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(dwarf::DW_LNE_set_address, 1);
932*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(Row.Address, PointerSize);
933*9880d681SAndroid Build Coastguard Worker LineSectionSize += 2 + PointerSize + getULEB128Size(PointerSize + 1);
934*9880d681SAndroid Build Coastguard Worker AddressDelta = 0;
935*9880d681SAndroid Build Coastguard Worker } else {
936*9880d681SAndroid Build Coastguard Worker AddressDelta = (Row.Address - Address) / MinInstLength;
937*9880d681SAndroid Build Coastguard Worker }
938*9880d681SAndroid Build Coastguard Worker
939*9880d681SAndroid Build Coastguard Worker // FIXME: code copied and transfromed from
940*9880d681SAndroid Build Coastguard Worker // MCDwarf.cpp::EmitDwarfLineTable. We should find a way to share
941*9880d681SAndroid Build Coastguard Worker // this code, but the current compatibility requirement with
942*9880d681SAndroid Build Coastguard Worker // classic dsymutil makes it hard. Revisit that once this
943*9880d681SAndroid Build Coastguard Worker // requirement is dropped.
944*9880d681SAndroid Build Coastguard Worker
945*9880d681SAndroid Build Coastguard Worker if (FileNum != Row.File) {
946*9880d681SAndroid Build Coastguard Worker FileNum = Row.File;
947*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(dwarf::DW_LNS_set_file, 1);
948*9880d681SAndroid Build Coastguard Worker MS->EmitULEB128IntValue(FileNum);
949*9880d681SAndroid Build Coastguard Worker LineSectionSize += 1 + getULEB128Size(FileNum);
950*9880d681SAndroid Build Coastguard Worker }
951*9880d681SAndroid Build Coastguard Worker if (Column != Row.Column) {
952*9880d681SAndroid Build Coastguard Worker Column = Row.Column;
953*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
954*9880d681SAndroid Build Coastguard Worker MS->EmitULEB128IntValue(Column);
955*9880d681SAndroid Build Coastguard Worker LineSectionSize += 1 + getULEB128Size(Column);
956*9880d681SAndroid Build Coastguard Worker }
957*9880d681SAndroid Build Coastguard Worker
958*9880d681SAndroid Build Coastguard Worker // FIXME: We should handle the discriminator here, but dsymutil
959*9880d681SAndroid Build Coastguard Worker // doesn' consider it, thus ignore it for now.
960*9880d681SAndroid Build Coastguard Worker
961*9880d681SAndroid Build Coastguard Worker if (Isa != Row.Isa) {
962*9880d681SAndroid Build Coastguard Worker Isa = Row.Isa;
963*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
964*9880d681SAndroid Build Coastguard Worker MS->EmitULEB128IntValue(Isa);
965*9880d681SAndroid Build Coastguard Worker LineSectionSize += 1 + getULEB128Size(Isa);
966*9880d681SAndroid Build Coastguard Worker }
967*9880d681SAndroid Build Coastguard Worker if (IsStatement != Row.IsStmt) {
968*9880d681SAndroid Build Coastguard Worker IsStatement = Row.IsStmt;
969*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1);
970*9880d681SAndroid Build Coastguard Worker LineSectionSize += 1;
971*9880d681SAndroid Build Coastguard Worker }
972*9880d681SAndroid Build Coastguard Worker if (Row.BasicBlock) {
973*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(dwarf::DW_LNS_set_basic_block, 1);
974*9880d681SAndroid Build Coastguard Worker LineSectionSize += 1;
975*9880d681SAndroid Build Coastguard Worker }
976*9880d681SAndroid Build Coastguard Worker
977*9880d681SAndroid Build Coastguard Worker if (Row.PrologueEnd) {
978*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
979*9880d681SAndroid Build Coastguard Worker LineSectionSize += 1;
980*9880d681SAndroid Build Coastguard Worker }
981*9880d681SAndroid Build Coastguard Worker
982*9880d681SAndroid Build Coastguard Worker if (Row.EpilogueBegin) {
983*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);
984*9880d681SAndroid Build Coastguard Worker LineSectionSize += 1;
985*9880d681SAndroid Build Coastguard Worker }
986*9880d681SAndroid Build Coastguard Worker
987*9880d681SAndroid Build Coastguard Worker int64_t LineDelta = int64_t(Row.Line) - LastLine;
988*9880d681SAndroid Build Coastguard Worker if (!Row.EndSequence) {
989*9880d681SAndroid Build Coastguard Worker MCDwarfLineAddr::Encode(*MC, Params, LineDelta, AddressDelta, EncodingOS);
990*9880d681SAndroid Build Coastguard Worker MS->EmitBytes(EncodingOS.str());
991*9880d681SAndroid Build Coastguard Worker LineSectionSize += EncodingBuffer.size();
992*9880d681SAndroid Build Coastguard Worker EncodingBuffer.resize(0);
993*9880d681SAndroid Build Coastguard Worker Address = Row.Address;
994*9880d681SAndroid Build Coastguard Worker LastLine = Row.Line;
995*9880d681SAndroid Build Coastguard Worker RowsSinceLastSequence++;
996*9880d681SAndroid Build Coastguard Worker } else {
997*9880d681SAndroid Build Coastguard Worker if (LineDelta) {
998*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(dwarf::DW_LNS_advance_line, 1);
999*9880d681SAndroid Build Coastguard Worker MS->EmitSLEB128IntValue(LineDelta);
1000*9880d681SAndroid Build Coastguard Worker LineSectionSize += 1 + getSLEB128Size(LineDelta);
1001*9880d681SAndroid Build Coastguard Worker }
1002*9880d681SAndroid Build Coastguard Worker if (AddressDelta) {
1003*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(dwarf::DW_LNS_advance_pc, 1);
1004*9880d681SAndroid Build Coastguard Worker MS->EmitULEB128IntValue(AddressDelta);
1005*9880d681SAndroid Build Coastguard Worker LineSectionSize += 1 + getULEB128Size(AddressDelta);
1006*9880d681SAndroid Build Coastguard Worker }
1007*9880d681SAndroid Build Coastguard Worker MCDwarfLineAddr::Encode(*MC, Params, INT64_MAX, 0, EncodingOS);
1008*9880d681SAndroid Build Coastguard Worker MS->EmitBytes(EncodingOS.str());
1009*9880d681SAndroid Build Coastguard Worker LineSectionSize += EncodingBuffer.size();
1010*9880d681SAndroid Build Coastguard Worker EncodingBuffer.resize(0);
1011*9880d681SAndroid Build Coastguard Worker Address = -1ULL;
1012*9880d681SAndroid Build Coastguard Worker LastLine = FileNum = IsStatement = 1;
1013*9880d681SAndroid Build Coastguard Worker RowsSinceLastSequence = Column = Isa = 0;
1014*9880d681SAndroid Build Coastguard Worker }
1015*9880d681SAndroid Build Coastguard Worker }
1016*9880d681SAndroid Build Coastguard Worker
1017*9880d681SAndroid Build Coastguard Worker if (RowsSinceLastSequence) {
1018*9880d681SAndroid Build Coastguard Worker MCDwarfLineAddr::Encode(*MC, Params, INT64_MAX, 0, EncodingOS);
1019*9880d681SAndroid Build Coastguard Worker MS->EmitBytes(EncodingOS.str());
1020*9880d681SAndroid Build Coastguard Worker LineSectionSize += EncodingBuffer.size();
1021*9880d681SAndroid Build Coastguard Worker EncodingBuffer.resize(0);
1022*9880d681SAndroid Build Coastguard Worker }
1023*9880d681SAndroid Build Coastguard Worker
1024*9880d681SAndroid Build Coastguard Worker MS->EmitLabel(LineEndSym);
1025*9880d681SAndroid Build Coastguard Worker }
1026*9880d681SAndroid Build Coastguard Worker
1027*9880d681SAndroid Build Coastguard Worker /// \brief Emit the pubnames or pubtypes section contribution for \p
1028*9880d681SAndroid Build Coastguard Worker /// Unit into \p Sec. The data is provided in \p Names.
emitPubSectionForUnit(MCSection * Sec,StringRef SecName,const CompileUnit & Unit,const std::vector<CompileUnit::AccelInfo> & Names)1029*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitPubSectionForUnit(
1030*9880d681SAndroid Build Coastguard Worker MCSection *Sec, StringRef SecName, const CompileUnit &Unit,
1031*9880d681SAndroid Build Coastguard Worker const std::vector<CompileUnit::AccelInfo> &Names) {
1032*9880d681SAndroid Build Coastguard Worker if (Names.empty())
1033*9880d681SAndroid Build Coastguard Worker return;
1034*9880d681SAndroid Build Coastguard Worker
1035*9880d681SAndroid Build Coastguard Worker // Start the dwarf pubnames section.
1036*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->SwitchSection(Sec);
1037*9880d681SAndroid Build Coastguard Worker MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + SecName + "_begin");
1038*9880d681SAndroid Build Coastguard Worker MCSymbol *EndLabel = Asm->createTempSymbol("pub" + SecName + "_end");
1039*9880d681SAndroid Build Coastguard Worker
1040*9880d681SAndroid Build Coastguard Worker bool HeaderEmitted = false;
1041*9880d681SAndroid Build Coastguard Worker // Emit the pubnames for this compilation unit.
1042*9880d681SAndroid Build Coastguard Worker for (const auto &Name : Names) {
1043*9880d681SAndroid Build Coastguard Worker if (Name.SkipPubSection)
1044*9880d681SAndroid Build Coastguard Worker continue;
1045*9880d681SAndroid Build Coastguard Worker
1046*9880d681SAndroid Build Coastguard Worker if (!HeaderEmitted) {
1047*9880d681SAndroid Build Coastguard Worker // Emit the header.
1048*9880d681SAndroid Build Coastguard Worker Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Length
1049*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitLabel(BeginLabel);
1050*9880d681SAndroid Build Coastguard Worker Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); // Version
1051*9880d681SAndroid Build Coastguard Worker Asm->EmitInt32(Unit.getStartOffset()); // Unit offset
1052*9880d681SAndroid Build Coastguard Worker Asm->EmitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset()); // Size
1053*9880d681SAndroid Build Coastguard Worker HeaderEmitted = true;
1054*9880d681SAndroid Build Coastguard Worker }
1055*9880d681SAndroid Build Coastguard Worker Asm->EmitInt32(Name.Die->getOffset());
1056*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitBytes(
1057*9880d681SAndroid Build Coastguard Worker StringRef(Name.Name.data(), Name.Name.size() + 1));
1058*9880d681SAndroid Build Coastguard Worker }
1059*9880d681SAndroid Build Coastguard Worker
1060*9880d681SAndroid Build Coastguard Worker if (!HeaderEmitted)
1061*9880d681SAndroid Build Coastguard Worker return;
1062*9880d681SAndroid Build Coastguard Worker Asm->EmitInt32(0); // End marker.
1063*9880d681SAndroid Build Coastguard Worker Asm->OutStreamer->EmitLabel(EndLabel);
1064*9880d681SAndroid Build Coastguard Worker }
1065*9880d681SAndroid Build Coastguard Worker
1066*9880d681SAndroid Build Coastguard Worker /// \brief Emit .debug_pubnames for \p Unit.
emitPubNamesForUnit(const CompileUnit & Unit)1067*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) {
1068*9880d681SAndroid Build Coastguard Worker emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(),
1069*9880d681SAndroid Build Coastguard Worker "names", Unit, Unit.getPubnames());
1070*9880d681SAndroid Build Coastguard Worker }
1071*9880d681SAndroid Build Coastguard Worker
1072*9880d681SAndroid Build Coastguard Worker /// \brief Emit .debug_pubtypes for \p Unit.
emitPubTypesForUnit(const CompileUnit & Unit)1073*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) {
1074*9880d681SAndroid Build Coastguard Worker emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(),
1075*9880d681SAndroid Build Coastguard Worker "types", Unit, Unit.getPubtypes());
1076*9880d681SAndroid Build Coastguard Worker }
1077*9880d681SAndroid Build Coastguard Worker
1078*9880d681SAndroid Build Coastguard Worker /// \brief Emit a CIE into the debug_frame section.
emitCIE(StringRef CIEBytes)1079*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitCIE(StringRef CIEBytes) {
1080*9880d681SAndroid Build Coastguard Worker MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
1081*9880d681SAndroid Build Coastguard Worker
1082*9880d681SAndroid Build Coastguard Worker MS->EmitBytes(CIEBytes);
1083*9880d681SAndroid Build Coastguard Worker FrameSectionSize += CIEBytes.size();
1084*9880d681SAndroid Build Coastguard Worker }
1085*9880d681SAndroid Build Coastguard Worker
1086*9880d681SAndroid Build Coastguard Worker /// \brief Emit a FDE into the debug_frame section. \p FDEBytes
1087*9880d681SAndroid Build Coastguard Worker /// contains the FDE data without the length, CIE offset and address
1088*9880d681SAndroid Build Coastguard Worker /// which will be replaced with the paramter values.
emitFDE(uint32_t CIEOffset,uint32_t AddrSize,uint32_t Address,StringRef FDEBytes)1089*9880d681SAndroid Build Coastguard Worker void DwarfStreamer::emitFDE(uint32_t CIEOffset, uint32_t AddrSize,
1090*9880d681SAndroid Build Coastguard Worker uint32_t Address, StringRef FDEBytes) {
1091*9880d681SAndroid Build Coastguard Worker MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
1092*9880d681SAndroid Build Coastguard Worker
1093*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(FDEBytes.size() + 4 + AddrSize, 4);
1094*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(CIEOffset, 4);
1095*9880d681SAndroid Build Coastguard Worker MS->EmitIntValue(Address, AddrSize);
1096*9880d681SAndroid Build Coastguard Worker MS->EmitBytes(FDEBytes);
1097*9880d681SAndroid Build Coastguard Worker FrameSectionSize += FDEBytes.size() + 8 + AddrSize;
1098*9880d681SAndroid Build Coastguard Worker }
1099*9880d681SAndroid Build Coastguard Worker
1100*9880d681SAndroid Build Coastguard Worker /// \brief The core of the Dwarf linking logic.
1101*9880d681SAndroid Build Coastguard Worker ///
1102*9880d681SAndroid Build Coastguard Worker /// The link of the dwarf information from the object files will be
1103*9880d681SAndroid Build Coastguard Worker /// driven by the selection of 'root DIEs', which are DIEs that
1104*9880d681SAndroid Build Coastguard Worker /// describe variables or functions that are present in the linked
1105*9880d681SAndroid Build Coastguard Worker /// binary (and thus have entries in the debug map). All the debug
1106*9880d681SAndroid Build Coastguard Worker /// information that will be linked (the DIEs, but also the line
1107*9880d681SAndroid Build Coastguard Worker /// tables, ranges, ...) is derived from that set of root DIEs.
1108*9880d681SAndroid Build Coastguard Worker ///
1109*9880d681SAndroid Build Coastguard Worker /// The root DIEs are identified because they contain relocations that
1110*9880d681SAndroid Build Coastguard Worker /// correspond to a debug map entry at specific places (the low_pc for
1111*9880d681SAndroid Build Coastguard Worker /// a function, the location for a variable). These relocations are
1112*9880d681SAndroid Build Coastguard Worker /// called ValidRelocs in the DwarfLinker and are gathered as a very
1113*9880d681SAndroid Build Coastguard Worker /// first step when we start processing a DebugMapObject.
1114*9880d681SAndroid Build Coastguard Worker class DwarfLinker {
1115*9880d681SAndroid Build Coastguard Worker public:
DwarfLinker(StringRef OutputFilename,const LinkOptions & Options)1116*9880d681SAndroid Build Coastguard Worker DwarfLinker(StringRef OutputFilename, const LinkOptions &Options)
1117*9880d681SAndroid Build Coastguard Worker : OutputFilename(OutputFilename), Options(Options),
1118*9880d681SAndroid Build Coastguard Worker BinHolder(Options.Verbose), LastCIEOffset(0) {}
1119*9880d681SAndroid Build Coastguard Worker
1120*9880d681SAndroid Build Coastguard Worker /// \brief Link the contents of the DebugMap.
1121*9880d681SAndroid Build Coastguard Worker bool link(const DebugMap &);
1122*9880d681SAndroid Build Coastguard Worker
1123*9880d681SAndroid Build Coastguard Worker void reportWarning(const Twine &Warning, const DWARFUnit *Unit = nullptr,
1124*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal *DIE = nullptr) const;
1125*9880d681SAndroid Build Coastguard Worker
1126*9880d681SAndroid Build Coastguard Worker private:
1127*9880d681SAndroid Build Coastguard Worker /// \brief Called at the start of a debug object link.
1128*9880d681SAndroid Build Coastguard Worker void startDebugObject(DWARFContext &, DebugMapObject &);
1129*9880d681SAndroid Build Coastguard Worker
1130*9880d681SAndroid Build Coastguard Worker /// \brief Called at the end of a debug object link.
1131*9880d681SAndroid Build Coastguard Worker void endDebugObject();
1132*9880d681SAndroid Build Coastguard Worker
1133*9880d681SAndroid Build Coastguard Worker /// Keeps track of relocations.
1134*9880d681SAndroid Build Coastguard Worker class RelocationManager {
1135*9880d681SAndroid Build Coastguard Worker struct ValidReloc {
1136*9880d681SAndroid Build Coastguard Worker uint32_t Offset;
1137*9880d681SAndroid Build Coastguard Worker uint32_t Size;
1138*9880d681SAndroid Build Coastguard Worker uint64_t Addend;
1139*9880d681SAndroid Build Coastguard Worker const DebugMapObject::DebugMapEntry *Mapping;
1140*9880d681SAndroid Build Coastguard Worker
ValidRelocllvm::dsymutil::__anon73f354850111::DwarfLinker::RelocationManager::ValidReloc1141*9880d681SAndroid Build Coastguard Worker ValidReloc(uint32_t Offset, uint32_t Size, uint64_t Addend,
1142*9880d681SAndroid Build Coastguard Worker const DebugMapObject::DebugMapEntry *Mapping)
1143*9880d681SAndroid Build Coastguard Worker : Offset(Offset), Size(Size), Addend(Addend), Mapping(Mapping) {}
1144*9880d681SAndroid Build Coastguard Worker
operator <llvm::dsymutil::__anon73f354850111::DwarfLinker::RelocationManager::ValidReloc1145*9880d681SAndroid Build Coastguard Worker bool operator<(const ValidReloc &RHS) const {
1146*9880d681SAndroid Build Coastguard Worker return Offset < RHS.Offset;
1147*9880d681SAndroid Build Coastguard Worker }
1148*9880d681SAndroid Build Coastguard Worker };
1149*9880d681SAndroid Build Coastguard Worker
1150*9880d681SAndroid Build Coastguard Worker DwarfLinker &Linker;
1151*9880d681SAndroid Build Coastguard Worker
1152*9880d681SAndroid Build Coastguard Worker /// \brief The valid relocations for the current DebugMapObject.
1153*9880d681SAndroid Build Coastguard Worker /// This vector is sorted by relocation offset.
1154*9880d681SAndroid Build Coastguard Worker std::vector<ValidReloc> ValidRelocs;
1155*9880d681SAndroid Build Coastguard Worker
1156*9880d681SAndroid Build Coastguard Worker /// \brief Index into ValidRelocs of the next relocation to
1157*9880d681SAndroid Build Coastguard Worker /// consider. As we walk the DIEs in acsending file offset and as
1158*9880d681SAndroid Build Coastguard Worker /// ValidRelocs is sorted by file offset, keeping this index
1159*9880d681SAndroid Build Coastguard Worker /// uptodate is all we have to do to have a cheap lookup during the
1160*9880d681SAndroid Build Coastguard Worker /// root DIE selection and during DIE cloning.
1161*9880d681SAndroid Build Coastguard Worker unsigned NextValidReloc;
1162*9880d681SAndroid Build Coastguard Worker
1163*9880d681SAndroid Build Coastguard Worker public:
RelocationManager(DwarfLinker & Linker)1164*9880d681SAndroid Build Coastguard Worker RelocationManager(DwarfLinker &Linker)
1165*9880d681SAndroid Build Coastguard Worker : Linker(Linker), NextValidReloc(0) {}
1166*9880d681SAndroid Build Coastguard Worker
hasValidRelocs() const1167*9880d681SAndroid Build Coastguard Worker bool hasValidRelocs() const { return !ValidRelocs.empty(); }
1168*9880d681SAndroid Build Coastguard Worker /// \brief Reset the NextValidReloc counter.
resetValidRelocs()1169*9880d681SAndroid Build Coastguard Worker void resetValidRelocs() { NextValidReloc = 0; }
1170*9880d681SAndroid Build Coastguard Worker
1171*9880d681SAndroid Build Coastguard Worker /// \defgroup FindValidRelocations Translate debug map into a list
1172*9880d681SAndroid Build Coastguard Worker /// of relevant relocations
1173*9880d681SAndroid Build Coastguard Worker ///
1174*9880d681SAndroid Build Coastguard Worker /// @{
1175*9880d681SAndroid Build Coastguard Worker bool findValidRelocsInDebugInfo(const object::ObjectFile &Obj,
1176*9880d681SAndroid Build Coastguard Worker const DebugMapObject &DMO);
1177*9880d681SAndroid Build Coastguard Worker
1178*9880d681SAndroid Build Coastguard Worker bool findValidRelocs(const object::SectionRef &Section,
1179*9880d681SAndroid Build Coastguard Worker const object::ObjectFile &Obj,
1180*9880d681SAndroid Build Coastguard Worker const DebugMapObject &DMO);
1181*9880d681SAndroid Build Coastguard Worker
1182*9880d681SAndroid Build Coastguard Worker void findValidRelocsMachO(const object::SectionRef &Section,
1183*9880d681SAndroid Build Coastguard Worker const object::MachOObjectFile &Obj,
1184*9880d681SAndroid Build Coastguard Worker const DebugMapObject &DMO);
1185*9880d681SAndroid Build Coastguard Worker /// @}
1186*9880d681SAndroid Build Coastguard Worker
1187*9880d681SAndroid Build Coastguard Worker bool hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset,
1188*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &Info);
1189*9880d681SAndroid Build Coastguard Worker
1190*9880d681SAndroid Build Coastguard Worker bool applyValidRelocs(MutableArrayRef<char> Data, uint32_t BaseOffset,
1191*9880d681SAndroid Build Coastguard Worker bool isLittleEndian);
1192*9880d681SAndroid Build Coastguard Worker };
1193*9880d681SAndroid Build Coastguard Worker
1194*9880d681SAndroid Build Coastguard Worker /// \defgroup FindRootDIEs Find DIEs corresponding to debug map entries.
1195*9880d681SAndroid Build Coastguard Worker ///
1196*9880d681SAndroid Build Coastguard Worker /// @{
1197*9880d681SAndroid Build Coastguard Worker /// \brief Recursively walk the \p DIE tree and look for DIEs to
1198*9880d681SAndroid Build Coastguard Worker /// keep. Store that information in \p CU's DIEInfo.
1199*9880d681SAndroid Build Coastguard Worker void lookForDIEsToKeep(RelocationManager &RelocMgr,
1200*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &DIE,
1201*9880d681SAndroid Build Coastguard Worker const DebugMapObject &DMO, CompileUnit &CU,
1202*9880d681SAndroid Build Coastguard Worker unsigned Flags);
1203*9880d681SAndroid Build Coastguard Worker
1204*9880d681SAndroid Build Coastguard Worker /// If this compile unit is really a skeleton CU that points to a
1205*9880d681SAndroid Build Coastguard Worker /// clang module, register it in ClangModules and return true.
1206*9880d681SAndroid Build Coastguard Worker ///
1207*9880d681SAndroid Build Coastguard Worker /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
1208*9880d681SAndroid Build Coastguard Worker /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
1209*9880d681SAndroid Build Coastguard Worker /// hash.
1210*9880d681SAndroid Build Coastguard Worker bool registerModuleReference(const DWARFDebugInfoEntryMinimal &CUDie,
1211*9880d681SAndroid Build Coastguard Worker const DWARFUnit &Unit, DebugMap &ModuleMap,
1212*9880d681SAndroid Build Coastguard Worker unsigned Indent = 0);
1213*9880d681SAndroid Build Coastguard Worker
1214*9880d681SAndroid Build Coastguard Worker /// Recursively add the debug info in this clang module .pcm
1215*9880d681SAndroid Build Coastguard Worker /// file (and all the modules imported by it in a bottom-up fashion)
1216*9880d681SAndroid Build Coastguard Worker /// to Units.
1217*9880d681SAndroid Build Coastguard Worker void loadClangModule(StringRef Filename, StringRef ModulePath,
1218*9880d681SAndroid Build Coastguard Worker StringRef ModuleName, uint64_t DwoId,
1219*9880d681SAndroid Build Coastguard Worker DebugMap &ModuleMap, unsigned Indent = 0);
1220*9880d681SAndroid Build Coastguard Worker
1221*9880d681SAndroid Build Coastguard Worker /// \brief Flags passed to DwarfLinker::lookForDIEsToKeep
1222*9880d681SAndroid Build Coastguard Worker enum TravesalFlags {
1223*9880d681SAndroid Build Coastguard Worker TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept.
1224*9880d681SAndroid Build Coastguard Worker TF_InFunctionScope = 1 << 1, ///< Current scope is a fucntion scope.
1225*9880d681SAndroid Build Coastguard Worker TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE.
1226*9880d681SAndroid Build Coastguard Worker TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE.
1227*9880d681SAndroid Build Coastguard Worker TF_ODR = 1 << 4, ///< Use the ODR whhile keeping dependants.
1228*9880d681SAndroid Build Coastguard Worker TF_SkipPC = 1 << 5, ///< Skip all location attributes.
1229*9880d681SAndroid Build Coastguard Worker };
1230*9880d681SAndroid Build Coastguard Worker
1231*9880d681SAndroid Build Coastguard Worker /// \brief Mark the passed DIE as well as all the ones it depends on
1232*9880d681SAndroid Build Coastguard Worker /// as kept.
1233*9880d681SAndroid Build Coastguard Worker void keepDIEAndDependencies(RelocationManager &RelocMgr,
1234*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &DIE,
1235*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &MyInfo,
1236*9880d681SAndroid Build Coastguard Worker const DebugMapObject &DMO, CompileUnit &CU,
1237*9880d681SAndroid Build Coastguard Worker bool UseODR);
1238*9880d681SAndroid Build Coastguard Worker
1239*9880d681SAndroid Build Coastguard Worker unsigned shouldKeepDIE(RelocationManager &RelocMgr,
1240*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &DIE,
1241*9880d681SAndroid Build Coastguard Worker CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
1242*9880d681SAndroid Build Coastguard Worker unsigned Flags);
1243*9880d681SAndroid Build Coastguard Worker
1244*9880d681SAndroid Build Coastguard Worker unsigned shouldKeepVariableDIE(RelocationManager &RelocMgr,
1245*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &DIE,
1246*9880d681SAndroid Build Coastguard Worker CompileUnit &Unit,
1247*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &MyInfo, unsigned Flags);
1248*9880d681SAndroid Build Coastguard Worker
1249*9880d681SAndroid Build Coastguard Worker unsigned shouldKeepSubprogramDIE(RelocationManager &RelocMgr,
1250*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &DIE,
1251*9880d681SAndroid Build Coastguard Worker CompileUnit &Unit,
1252*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &MyInfo,
1253*9880d681SAndroid Build Coastguard Worker unsigned Flags);
1254*9880d681SAndroid Build Coastguard Worker
1255*9880d681SAndroid Build Coastguard Worker bool hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset,
1256*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &Info);
1257*9880d681SAndroid Build Coastguard Worker /// @}
1258*9880d681SAndroid Build Coastguard Worker
1259*9880d681SAndroid Build Coastguard Worker /// \defgroup Linking Methods used to link the debug information
1260*9880d681SAndroid Build Coastguard Worker ///
1261*9880d681SAndroid Build Coastguard Worker /// @{
1262*9880d681SAndroid Build Coastguard Worker
1263*9880d681SAndroid Build Coastguard Worker class DIECloner {
1264*9880d681SAndroid Build Coastguard Worker DwarfLinker &Linker;
1265*9880d681SAndroid Build Coastguard Worker RelocationManager &RelocMgr;
1266*9880d681SAndroid Build Coastguard Worker /// Allocator used for all the DIEValue objects.
1267*9880d681SAndroid Build Coastguard Worker BumpPtrAllocator &DIEAlloc;
1268*9880d681SAndroid Build Coastguard Worker MutableArrayRef<CompileUnit> CompileUnits;
1269*9880d681SAndroid Build Coastguard Worker LinkOptions Options;
1270*9880d681SAndroid Build Coastguard Worker
1271*9880d681SAndroid Build Coastguard Worker public:
DIECloner(DwarfLinker & Linker,RelocationManager & RelocMgr,BumpPtrAllocator & DIEAlloc,MutableArrayRef<CompileUnit> CompileUnits,LinkOptions & Options)1272*9880d681SAndroid Build Coastguard Worker DIECloner(DwarfLinker &Linker, RelocationManager &RelocMgr,
1273*9880d681SAndroid Build Coastguard Worker BumpPtrAllocator &DIEAlloc,
1274*9880d681SAndroid Build Coastguard Worker MutableArrayRef<CompileUnit> CompileUnits, LinkOptions &Options)
1275*9880d681SAndroid Build Coastguard Worker : Linker(Linker), RelocMgr(RelocMgr), DIEAlloc(DIEAlloc),
1276*9880d681SAndroid Build Coastguard Worker CompileUnits(CompileUnits), Options(Options) {}
1277*9880d681SAndroid Build Coastguard Worker
1278*9880d681SAndroid Build Coastguard Worker /// Recursively clone \p InputDIE into an tree of DIE objects
1279*9880d681SAndroid Build Coastguard Worker /// where useless (as decided by lookForDIEsToKeep()) bits have been
1280*9880d681SAndroid Build Coastguard Worker /// stripped out and addresses have been rewritten according to the
1281*9880d681SAndroid Build Coastguard Worker /// debug map.
1282*9880d681SAndroid Build Coastguard Worker ///
1283*9880d681SAndroid Build Coastguard Worker /// \param OutOffset is the offset the cloned DIE in the output
1284*9880d681SAndroid Build Coastguard Worker /// compile unit.
1285*9880d681SAndroid Build Coastguard Worker /// \param PCOffset (while cloning a function scope) is the offset
1286*9880d681SAndroid Build Coastguard Worker /// applied to the entry point of the function to get the linked address.
1287*9880d681SAndroid Build Coastguard Worker ///
1288*9880d681SAndroid Build Coastguard Worker /// \returns the root of the cloned tree or null if nothing was selected.
1289*9880d681SAndroid Build Coastguard Worker DIE *cloneDIE(const DWARFDebugInfoEntryMinimal &InputDIE, CompileUnit &U,
1290*9880d681SAndroid Build Coastguard Worker int64_t PCOffset, uint32_t OutOffset, unsigned Flags);
1291*9880d681SAndroid Build Coastguard Worker
1292*9880d681SAndroid Build Coastguard Worker /// Construct the output DIE tree by cloning the DIEs we
1293*9880d681SAndroid Build Coastguard Worker /// chose to keep above. If there are no valid relocs, then there's
1294*9880d681SAndroid Build Coastguard Worker /// nothing to clone/emit.
1295*9880d681SAndroid Build Coastguard Worker void cloneAllCompileUnits(DWARFContextInMemory &DwarfContext);
1296*9880d681SAndroid Build Coastguard Worker
1297*9880d681SAndroid Build Coastguard Worker private:
1298*9880d681SAndroid Build Coastguard Worker typedef DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec;
1299*9880d681SAndroid Build Coastguard Worker
1300*9880d681SAndroid Build Coastguard Worker /// Information gathered and exchanged between the various
1301*9880d681SAndroid Build Coastguard Worker /// clone*Attributes helpers about the attributes of a particular DIE.
1302*9880d681SAndroid Build Coastguard Worker struct AttributesInfo {
1303*9880d681SAndroid Build Coastguard Worker const char *Name, *MangledName; ///< Names.
1304*9880d681SAndroid Build Coastguard Worker uint32_t NameOffset, MangledNameOffset; ///< Offsets in the string pool.
1305*9880d681SAndroid Build Coastguard Worker
1306*9880d681SAndroid Build Coastguard Worker uint64_t OrigLowPc; ///< Value of AT_low_pc in the input DIE
1307*9880d681SAndroid Build Coastguard Worker uint64_t OrigHighPc; ///< Value of AT_high_pc in the input DIE
1308*9880d681SAndroid Build Coastguard Worker int64_t PCOffset; ///< Offset to apply to PC addresses inside a function.
1309*9880d681SAndroid Build Coastguard Worker
1310*9880d681SAndroid Build Coastguard Worker bool HasLowPc; ///< Does the DIE have a low_pc attribute?
1311*9880d681SAndroid Build Coastguard Worker bool IsDeclaration; ///< Is this DIE only a declaration?
1312*9880d681SAndroid Build Coastguard Worker
AttributesInfollvm::dsymutil::__anon73f354850111::DwarfLinker::DIECloner::AttributesInfo1313*9880d681SAndroid Build Coastguard Worker AttributesInfo()
1314*9880d681SAndroid Build Coastguard Worker : Name(nullptr), MangledName(nullptr), NameOffset(0),
1315*9880d681SAndroid Build Coastguard Worker MangledNameOffset(0), OrigLowPc(UINT64_MAX), OrigHighPc(0),
1316*9880d681SAndroid Build Coastguard Worker PCOffset(0), HasLowPc(false), IsDeclaration(false) {}
1317*9880d681SAndroid Build Coastguard Worker };
1318*9880d681SAndroid Build Coastguard Worker
1319*9880d681SAndroid Build Coastguard Worker /// Helper for cloneDIE.
1320*9880d681SAndroid Build Coastguard Worker unsigned cloneAttribute(DIE &Die,
1321*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &InputDIE,
1322*9880d681SAndroid Build Coastguard Worker CompileUnit &U, const DWARFFormValue &Val,
1323*9880d681SAndroid Build Coastguard Worker const AttributeSpec AttrSpec, unsigned AttrSize,
1324*9880d681SAndroid Build Coastguard Worker AttributesInfo &AttrInfo);
1325*9880d681SAndroid Build Coastguard Worker
1326*9880d681SAndroid Build Coastguard Worker /// Clone a string attribute described by \p AttrSpec and add
1327*9880d681SAndroid Build Coastguard Worker /// it to \p Die.
1328*9880d681SAndroid Build Coastguard Worker /// \returns the size of the new attribute.
1329*9880d681SAndroid Build Coastguard Worker unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
1330*9880d681SAndroid Build Coastguard Worker const DWARFFormValue &Val,
1331*9880d681SAndroid Build Coastguard Worker const DWARFUnit &U);
1332*9880d681SAndroid Build Coastguard Worker
1333*9880d681SAndroid Build Coastguard Worker /// Clone an attribute referencing another DIE and add
1334*9880d681SAndroid Build Coastguard Worker /// it to \p Die.
1335*9880d681SAndroid Build Coastguard Worker /// \returns the size of the new attribute.
1336*9880d681SAndroid Build Coastguard Worker unsigned
1337*9880d681SAndroid Build Coastguard Worker cloneDieReferenceAttribute(DIE &Die,
1338*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &InputDIE,
1339*9880d681SAndroid Build Coastguard Worker AttributeSpec AttrSpec, unsigned AttrSize,
1340*9880d681SAndroid Build Coastguard Worker const DWARFFormValue &Val, CompileUnit &Unit);
1341*9880d681SAndroid Build Coastguard Worker
1342*9880d681SAndroid Build Coastguard Worker /// Clone an attribute referencing another DIE and add
1343*9880d681SAndroid Build Coastguard Worker /// it to \p Die.
1344*9880d681SAndroid Build Coastguard Worker /// \returns the size of the new attribute.
1345*9880d681SAndroid Build Coastguard Worker unsigned cloneBlockAttribute(DIE &Die, AttributeSpec AttrSpec,
1346*9880d681SAndroid Build Coastguard Worker const DWARFFormValue &Val, unsigned AttrSize);
1347*9880d681SAndroid Build Coastguard Worker
1348*9880d681SAndroid Build Coastguard Worker /// Clone an attribute referencing another DIE and add
1349*9880d681SAndroid Build Coastguard Worker /// it to \p Die.
1350*9880d681SAndroid Build Coastguard Worker /// \returns the size of the new attribute.
1351*9880d681SAndroid Build Coastguard Worker unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
1352*9880d681SAndroid Build Coastguard Worker const DWARFFormValue &Val,
1353*9880d681SAndroid Build Coastguard Worker const CompileUnit &Unit,
1354*9880d681SAndroid Build Coastguard Worker AttributesInfo &Info);
1355*9880d681SAndroid Build Coastguard Worker
1356*9880d681SAndroid Build Coastguard Worker /// Clone a scalar attribute and add it to \p Die.
1357*9880d681SAndroid Build Coastguard Worker /// \returns the size of the new attribute.
1358*9880d681SAndroid Build Coastguard Worker unsigned cloneScalarAttribute(DIE &Die,
1359*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &InputDIE,
1360*9880d681SAndroid Build Coastguard Worker CompileUnit &U, AttributeSpec AttrSpec,
1361*9880d681SAndroid Build Coastguard Worker const DWARFFormValue &Val, unsigned AttrSize,
1362*9880d681SAndroid Build Coastguard Worker AttributesInfo &Info);
1363*9880d681SAndroid Build Coastguard Worker
1364*9880d681SAndroid Build Coastguard Worker /// Get the potential name and mangled name for the entity
1365*9880d681SAndroid Build Coastguard Worker /// described by \p Die and store them in \Info if they are not
1366*9880d681SAndroid Build Coastguard Worker /// already there.
1367*9880d681SAndroid Build Coastguard Worker /// \returns is a name was found.
1368*9880d681SAndroid Build Coastguard Worker bool getDIENames(const DWARFDebugInfoEntryMinimal &Die, DWARFUnit &U,
1369*9880d681SAndroid Build Coastguard Worker AttributesInfo &Info);
1370*9880d681SAndroid Build Coastguard Worker
1371*9880d681SAndroid Build Coastguard Worker /// Create a copy of abbreviation Abbrev.
1372*9880d681SAndroid Build Coastguard Worker void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR);
1373*9880d681SAndroid Build Coastguard Worker };
1374*9880d681SAndroid Build Coastguard Worker
1375*9880d681SAndroid Build Coastguard Worker /// \brief Assign an abbreviation number to \p Abbrev
1376*9880d681SAndroid Build Coastguard Worker void AssignAbbrev(DIEAbbrev &Abbrev);
1377*9880d681SAndroid Build Coastguard Worker
1378*9880d681SAndroid Build Coastguard Worker /// \brief FoldingSet that uniques the abbreviations.
1379*9880d681SAndroid Build Coastguard Worker FoldingSet<DIEAbbrev> AbbreviationsSet;
1380*9880d681SAndroid Build Coastguard Worker /// \brief Storage for the unique Abbreviations.
1381*9880d681SAndroid Build Coastguard Worker /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot
1382*9880d681SAndroid Build Coastguard Worker /// be changed to a vecot of unique_ptrs.
1383*9880d681SAndroid Build Coastguard Worker std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
1384*9880d681SAndroid Build Coastguard Worker
1385*9880d681SAndroid Build Coastguard Worker /// \brief Compute and emit debug_ranges section for \p Unit, and
1386*9880d681SAndroid Build Coastguard Worker /// patch the attributes referencing it.
1387*9880d681SAndroid Build Coastguard Worker void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf) const;
1388*9880d681SAndroid Build Coastguard Worker
1389*9880d681SAndroid Build Coastguard Worker /// \brief Generate and emit the DW_AT_ranges attribute for a
1390*9880d681SAndroid Build Coastguard Worker /// compile_unit if it had one.
1391*9880d681SAndroid Build Coastguard Worker void generateUnitRanges(CompileUnit &Unit) const;
1392*9880d681SAndroid Build Coastguard Worker
1393*9880d681SAndroid Build Coastguard Worker /// \brief Extract the line tables fromt he original dwarf, extract
1394*9880d681SAndroid Build Coastguard Worker /// the relevant parts according to the linked function ranges and
1395*9880d681SAndroid Build Coastguard Worker /// emit the result in the debug_line section.
1396*9880d681SAndroid Build Coastguard Worker void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf);
1397*9880d681SAndroid Build Coastguard Worker
1398*9880d681SAndroid Build Coastguard Worker /// \brief Emit the accelerator entries for \p Unit.
1399*9880d681SAndroid Build Coastguard Worker void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
1400*9880d681SAndroid Build Coastguard Worker
1401*9880d681SAndroid Build Coastguard Worker /// \brief Patch the frame info for an object file and emit it.
1402*9880d681SAndroid Build Coastguard Worker void patchFrameInfoForObject(const DebugMapObject &, DWARFContext &,
1403*9880d681SAndroid Build Coastguard Worker unsigned AddressSize);
1404*9880d681SAndroid Build Coastguard Worker
1405*9880d681SAndroid Build Coastguard Worker /// \brief DIELoc objects that need to be destructed (but not freed!).
1406*9880d681SAndroid Build Coastguard Worker std::vector<DIELoc *> DIELocs;
1407*9880d681SAndroid Build Coastguard Worker /// \brief DIEBlock objects that need to be destructed (but not freed!).
1408*9880d681SAndroid Build Coastguard Worker std::vector<DIEBlock *> DIEBlocks;
1409*9880d681SAndroid Build Coastguard Worker /// \brief Allocator used for all the DIEValue objects.
1410*9880d681SAndroid Build Coastguard Worker BumpPtrAllocator DIEAlloc;
1411*9880d681SAndroid Build Coastguard Worker /// @}
1412*9880d681SAndroid Build Coastguard Worker
1413*9880d681SAndroid Build Coastguard Worker /// ODR Contexts for that link.
1414*9880d681SAndroid Build Coastguard Worker DeclContextTree ODRContexts;
1415*9880d681SAndroid Build Coastguard Worker
1416*9880d681SAndroid Build Coastguard Worker /// \defgroup Helpers Various helper methods.
1417*9880d681SAndroid Build Coastguard Worker ///
1418*9880d681SAndroid Build Coastguard Worker /// @{
1419*9880d681SAndroid Build Coastguard Worker bool createStreamer(const Triple &TheTriple, StringRef OutputFilename);
1420*9880d681SAndroid Build Coastguard Worker
1421*9880d681SAndroid Build Coastguard Worker /// \brief Attempt to load a debug object from disk.
1422*9880d681SAndroid Build Coastguard Worker ErrorOr<const object::ObjectFile &> loadObject(BinaryHolder &BinaryHolder,
1423*9880d681SAndroid Build Coastguard Worker DebugMapObject &Obj,
1424*9880d681SAndroid Build Coastguard Worker const DebugMap &Map);
1425*9880d681SAndroid Build Coastguard Worker /// @}
1426*9880d681SAndroid Build Coastguard Worker
1427*9880d681SAndroid Build Coastguard Worker std::string OutputFilename;
1428*9880d681SAndroid Build Coastguard Worker LinkOptions Options;
1429*9880d681SAndroid Build Coastguard Worker BinaryHolder BinHolder;
1430*9880d681SAndroid Build Coastguard Worker std::unique_ptr<DwarfStreamer> Streamer;
1431*9880d681SAndroid Build Coastguard Worker uint64_t OutputDebugInfoSize;
1432*9880d681SAndroid Build Coastguard Worker unsigned UnitID; ///< A unique ID that identifies each compile unit.
1433*9880d681SAndroid Build Coastguard Worker
1434*9880d681SAndroid Build Coastguard Worker /// The units of the current debug map object.
1435*9880d681SAndroid Build Coastguard Worker std::vector<CompileUnit> Units;
1436*9880d681SAndroid Build Coastguard Worker
1437*9880d681SAndroid Build Coastguard Worker /// The debug map object currently under consideration.
1438*9880d681SAndroid Build Coastguard Worker DebugMapObject *CurrentDebugObject;
1439*9880d681SAndroid Build Coastguard Worker
1440*9880d681SAndroid Build Coastguard Worker /// \brief The Dwarf string pool
1441*9880d681SAndroid Build Coastguard Worker NonRelocatableStringpool StringPool;
1442*9880d681SAndroid Build Coastguard Worker
1443*9880d681SAndroid Build Coastguard Worker /// \brief This map is keyed by the entry PC of functions in that
1444*9880d681SAndroid Build Coastguard Worker /// debug object and the associated value is a pair storing the
1445*9880d681SAndroid Build Coastguard Worker /// corresponding end PC and the offset to apply to get the linked
1446*9880d681SAndroid Build Coastguard Worker /// address.
1447*9880d681SAndroid Build Coastguard Worker ///
1448*9880d681SAndroid Build Coastguard Worker /// See startDebugObject() for a more complete description of its use.
1449*9880d681SAndroid Build Coastguard Worker std::map<uint64_t, std::pair<uint64_t, int64_t>> Ranges;
1450*9880d681SAndroid Build Coastguard Worker
1451*9880d681SAndroid Build Coastguard Worker /// \brief The CIEs that have been emitted in the output
1452*9880d681SAndroid Build Coastguard Worker /// section. The actual CIE data serves a the key to this StringMap,
1453*9880d681SAndroid Build Coastguard Worker /// this takes care of comparing the semantics of CIEs defined in
1454*9880d681SAndroid Build Coastguard Worker /// different object files.
1455*9880d681SAndroid Build Coastguard Worker StringMap<uint32_t> EmittedCIEs;
1456*9880d681SAndroid Build Coastguard Worker
1457*9880d681SAndroid Build Coastguard Worker /// Offset of the last CIE that has been emitted in the output
1458*9880d681SAndroid Build Coastguard Worker /// debug_frame section.
1459*9880d681SAndroid Build Coastguard Worker uint32_t LastCIEOffset;
1460*9880d681SAndroid Build Coastguard Worker
1461*9880d681SAndroid Build Coastguard Worker /// Mapping the PCM filename to the DwoId.
1462*9880d681SAndroid Build Coastguard Worker StringMap<uint64_t> ClangModules;
1463*9880d681SAndroid Build Coastguard Worker
1464*9880d681SAndroid Build Coastguard Worker bool ModuleCacheHintDisplayed = false;
1465*9880d681SAndroid Build Coastguard Worker bool ArchiveHintDisplayed = false;
1466*9880d681SAndroid Build Coastguard Worker };
1467*9880d681SAndroid Build Coastguard Worker
1468*9880d681SAndroid Build Coastguard Worker /// Similar to DWARFUnitSection::getUnitForOffset(), but returning our
1469*9880d681SAndroid Build Coastguard Worker /// CompileUnit object instead.
getUnitForOffset(MutableArrayRef<CompileUnit> Units,unsigned Offset)1470*9880d681SAndroid Build Coastguard Worker static CompileUnit *getUnitForOffset(MutableArrayRef<CompileUnit> Units,
1471*9880d681SAndroid Build Coastguard Worker unsigned Offset) {
1472*9880d681SAndroid Build Coastguard Worker auto CU =
1473*9880d681SAndroid Build Coastguard Worker std::upper_bound(Units.begin(), Units.end(), Offset,
1474*9880d681SAndroid Build Coastguard Worker [](uint32_t LHS, const CompileUnit &RHS) {
1475*9880d681SAndroid Build Coastguard Worker return LHS < RHS.getOrigUnit().getNextUnitOffset();
1476*9880d681SAndroid Build Coastguard Worker });
1477*9880d681SAndroid Build Coastguard Worker return CU != Units.end() ? &*CU : nullptr;
1478*9880d681SAndroid Build Coastguard Worker }
1479*9880d681SAndroid Build Coastguard Worker
1480*9880d681SAndroid Build Coastguard Worker /// Resolve the DIE attribute reference that has been
1481*9880d681SAndroid Build Coastguard Worker /// extracted in \p RefValue. The resulting DIE migh be in another
1482*9880d681SAndroid Build Coastguard Worker /// CompileUnit which is stored into \p ReferencedCU.
1483*9880d681SAndroid Build Coastguard Worker /// \returns null if resolving fails for any reason.
resolveDIEReference(const DwarfLinker & Linker,MutableArrayRef<CompileUnit> Units,const DWARFFormValue & RefValue,const DWARFUnit & Unit,const DWARFDebugInfoEntryMinimal & DIE,CompileUnit * & RefCU)1484*9880d681SAndroid Build Coastguard Worker static const DWARFDebugInfoEntryMinimal *resolveDIEReference(
1485*9880d681SAndroid Build Coastguard Worker const DwarfLinker &Linker, MutableArrayRef<CompileUnit> Units,
1486*9880d681SAndroid Build Coastguard Worker const DWARFFormValue &RefValue, const DWARFUnit &Unit,
1487*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &DIE, CompileUnit *&RefCU) {
1488*9880d681SAndroid Build Coastguard Worker assert(RefValue.isFormClass(DWARFFormValue::FC_Reference));
1489*9880d681SAndroid Build Coastguard Worker uint64_t RefOffset = *RefValue.getAsReference(&Unit);
1490*9880d681SAndroid Build Coastguard Worker
1491*9880d681SAndroid Build Coastguard Worker if ((RefCU = getUnitForOffset(Units, RefOffset)))
1492*9880d681SAndroid Build Coastguard Worker if (const auto *RefDie = RefCU->getOrigUnit().getDIEForOffset(RefOffset))
1493*9880d681SAndroid Build Coastguard Worker return RefDie;
1494*9880d681SAndroid Build Coastguard Worker
1495*9880d681SAndroid Build Coastguard Worker Linker.reportWarning("could not find referenced DIE", &Unit, &DIE);
1496*9880d681SAndroid Build Coastguard Worker return nullptr;
1497*9880d681SAndroid Build Coastguard Worker }
1498*9880d681SAndroid Build Coastguard Worker
1499*9880d681SAndroid Build Coastguard Worker /// \returns whether the passed \a Attr type might contain a DIE
1500*9880d681SAndroid Build Coastguard Worker /// reference suitable for ODR uniquing.
isODRAttribute(uint16_t Attr)1501*9880d681SAndroid Build Coastguard Worker static bool isODRAttribute(uint16_t Attr) {
1502*9880d681SAndroid Build Coastguard Worker switch (Attr) {
1503*9880d681SAndroid Build Coastguard Worker default:
1504*9880d681SAndroid Build Coastguard Worker return false;
1505*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_type:
1506*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_containing_type:
1507*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_specification:
1508*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_abstract_origin:
1509*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_import:
1510*9880d681SAndroid Build Coastguard Worker return true;
1511*9880d681SAndroid Build Coastguard Worker }
1512*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Improper attribute.");
1513*9880d681SAndroid Build Coastguard Worker }
1514*9880d681SAndroid Build Coastguard Worker
1515*9880d681SAndroid Build Coastguard Worker /// Set the last DIE/CU a context was seen in and, possibly invalidate
1516*9880d681SAndroid Build Coastguard Worker /// the context if it is ambiguous.
1517*9880d681SAndroid Build Coastguard Worker ///
1518*9880d681SAndroid Build Coastguard Worker /// In the current implementation, we don't handle overloaded
1519*9880d681SAndroid Build Coastguard Worker /// functions well, because the argument types are not taken into
1520*9880d681SAndroid Build Coastguard Worker /// account when computing the DeclContext tree.
1521*9880d681SAndroid Build Coastguard Worker ///
1522*9880d681SAndroid Build Coastguard Worker /// Some of this is mitigated byt using mangled names that do contain
1523*9880d681SAndroid Build Coastguard Worker /// the arguments types, but sometimes (eg. with function templates)
1524*9880d681SAndroid Build Coastguard Worker /// we don't have that. In that case, just do not unique anything that
1525*9880d681SAndroid Build Coastguard Worker /// refers to the contexts we are not able to distinguish.
1526*9880d681SAndroid Build Coastguard Worker ///
1527*9880d681SAndroid Build Coastguard Worker /// If a context that is not a namespace appears twice in the same CU,
1528*9880d681SAndroid Build Coastguard Worker /// we know it is ambiguous. Make it invalid.
setLastSeenDIE(CompileUnit & U,const DWARFDebugInfoEntryMinimal * Die)1529*9880d681SAndroid Build Coastguard Worker bool DeclContext::setLastSeenDIE(CompileUnit &U,
1530*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal *Die) {
1531*9880d681SAndroid Build Coastguard Worker if (LastSeenCompileUnitID == U.getUniqueID()) {
1532*9880d681SAndroid Build Coastguard Worker DWARFUnit &OrigUnit = U.getOrigUnit();
1533*9880d681SAndroid Build Coastguard Worker uint32_t FirstIdx = OrigUnit.getDIEIndex(LastSeenDIE);
1534*9880d681SAndroid Build Coastguard Worker U.getInfo(FirstIdx).Ctxt = nullptr;
1535*9880d681SAndroid Build Coastguard Worker return false;
1536*9880d681SAndroid Build Coastguard Worker }
1537*9880d681SAndroid Build Coastguard Worker
1538*9880d681SAndroid Build Coastguard Worker LastSeenCompileUnitID = U.getUniqueID();
1539*9880d681SAndroid Build Coastguard Worker LastSeenDIE = Die;
1540*9880d681SAndroid Build Coastguard Worker return true;
1541*9880d681SAndroid Build Coastguard Worker }
1542*9880d681SAndroid Build Coastguard Worker
getChildDeclContext(DeclContext & Context,const DWARFDebugInfoEntryMinimal * DIE,CompileUnit & U,NonRelocatableStringpool & StringPool,bool InClangModule)1543*9880d681SAndroid Build Coastguard Worker PointerIntPair<DeclContext *, 1> DeclContextTree::getChildDeclContext(
1544*9880d681SAndroid Build Coastguard Worker DeclContext &Context, const DWARFDebugInfoEntryMinimal *DIE, CompileUnit &U,
1545*9880d681SAndroid Build Coastguard Worker NonRelocatableStringpool &StringPool, bool InClangModule) {
1546*9880d681SAndroid Build Coastguard Worker unsigned Tag = DIE->getTag();
1547*9880d681SAndroid Build Coastguard Worker
1548*9880d681SAndroid Build Coastguard Worker // FIXME: dsymutil-classic compat: We should bail out here if we
1549*9880d681SAndroid Build Coastguard Worker // have a specification or an abstract_origin. We will get the
1550*9880d681SAndroid Build Coastguard Worker // parent context wrong here.
1551*9880d681SAndroid Build Coastguard Worker
1552*9880d681SAndroid Build Coastguard Worker switch (Tag) {
1553*9880d681SAndroid Build Coastguard Worker default:
1554*9880d681SAndroid Build Coastguard Worker // By default stop gathering child contexts.
1555*9880d681SAndroid Build Coastguard Worker return PointerIntPair<DeclContext *, 1>(nullptr);
1556*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_module:
1557*9880d681SAndroid Build Coastguard Worker break;
1558*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_compile_unit:
1559*9880d681SAndroid Build Coastguard Worker return PointerIntPair<DeclContext *, 1>(&Context);
1560*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_subprogram:
1561*9880d681SAndroid Build Coastguard Worker // Do not unique anything inside CU local functions.
1562*9880d681SAndroid Build Coastguard Worker if ((Context.getTag() == dwarf::DW_TAG_namespace ||
1563*9880d681SAndroid Build Coastguard Worker Context.getTag() == dwarf::DW_TAG_compile_unit) &&
1564*9880d681SAndroid Build Coastguard Worker !DIE->getAttributeValueAsUnsignedConstant(&U.getOrigUnit(),
1565*9880d681SAndroid Build Coastguard Worker dwarf::DW_AT_external, 0))
1566*9880d681SAndroid Build Coastguard Worker return PointerIntPair<DeclContext *, 1>(nullptr);
1567*9880d681SAndroid Build Coastguard Worker // Fallthrough
1568*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_member:
1569*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_namespace:
1570*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_structure_type:
1571*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_class_type:
1572*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_union_type:
1573*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_enumeration_type:
1574*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_typedef:
1575*9880d681SAndroid Build Coastguard Worker // Artificial things might be ambiguous, because they might be
1576*9880d681SAndroid Build Coastguard Worker // created on demand. For example implicitely defined constructors
1577*9880d681SAndroid Build Coastguard Worker // are ambiguous because of the way we identify contexts, and they
1578*9880d681SAndroid Build Coastguard Worker // won't be generated everytime everywhere.
1579*9880d681SAndroid Build Coastguard Worker if (DIE->getAttributeValueAsUnsignedConstant(&U.getOrigUnit(),
1580*9880d681SAndroid Build Coastguard Worker dwarf::DW_AT_artificial, 0))
1581*9880d681SAndroid Build Coastguard Worker return PointerIntPair<DeclContext *, 1>(nullptr);
1582*9880d681SAndroid Build Coastguard Worker break;
1583*9880d681SAndroid Build Coastguard Worker }
1584*9880d681SAndroid Build Coastguard Worker
1585*9880d681SAndroid Build Coastguard Worker const char *Name = DIE->getName(&U.getOrigUnit(), DINameKind::LinkageName);
1586*9880d681SAndroid Build Coastguard Worker const char *ShortName = DIE->getName(&U.getOrigUnit(), DINameKind::ShortName);
1587*9880d681SAndroid Build Coastguard Worker StringRef NameRef;
1588*9880d681SAndroid Build Coastguard Worker StringRef ShortNameRef;
1589*9880d681SAndroid Build Coastguard Worker StringRef FileRef;
1590*9880d681SAndroid Build Coastguard Worker
1591*9880d681SAndroid Build Coastguard Worker if (Name)
1592*9880d681SAndroid Build Coastguard Worker NameRef = StringPool.internString(Name);
1593*9880d681SAndroid Build Coastguard Worker else if (Tag == dwarf::DW_TAG_namespace)
1594*9880d681SAndroid Build Coastguard Worker // FIXME: For dsymutil-classic compatibility. I think uniquing
1595*9880d681SAndroid Build Coastguard Worker // within anonymous namespaces is wrong. There is no ODR guarantee
1596*9880d681SAndroid Build Coastguard Worker // there.
1597*9880d681SAndroid Build Coastguard Worker NameRef = StringPool.internString("(anonymous namespace)");
1598*9880d681SAndroid Build Coastguard Worker
1599*9880d681SAndroid Build Coastguard Worker if (ShortName && ShortName != Name)
1600*9880d681SAndroid Build Coastguard Worker ShortNameRef = StringPool.internString(ShortName);
1601*9880d681SAndroid Build Coastguard Worker else
1602*9880d681SAndroid Build Coastguard Worker ShortNameRef = NameRef;
1603*9880d681SAndroid Build Coastguard Worker
1604*9880d681SAndroid Build Coastguard Worker if (Tag != dwarf::DW_TAG_class_type && Tag != dwarf::DW_TAG_structure_type &&
1605*9880d681SAndroid Build Coastguard Worker Tag != dwarf::DW_TAG_union_type &&
1606*9880d681SAndroid Build Coastguard Worker Tag != dwarf::DW_TAG_enumeration_type && NameRef.empty())
1607*9880d681SAndroid Build Coastguard Worker return PointerIntPair<DeclContext *, 1>(nullptr);
1608*9880d681SAndroid Build Coastguard Worker
1609*9880d681SAndroid Build Coastguard Worker unsigned Line = 0;
1610*9880d681SAndroid Build Coastguard Worker unsigned ByteSize = UINT32_MAX;
1611*9880d681SAndroid Build Coastguard Worker
1612*9880d681SAndroid Build Coastguard Worker if (!InClangModule) {
1613*9880d681SAndroid Build Coastguard Worker // Gather some discriminating data about the DeclContext we will be
1614*9880d681SAndroid Build Coastguard Worker // creating: File, line number and byte size. This shouldn't be
1615*9880d681SAndroid Build Coastguard Worker // necessary, because the ODR is just about names, but given that we
1616*9880d681SAndroid Build Coastguard Worker // do some approximations with overloaded functions and anonymous
1617*9880d681SAndroid Build Coastguard Worker // namespaces, use these additional data points to make the process
1618*9880d681SAndroid Build Coastguard Worker // safer. This is disabled for clang modules, because forward
1619*9880d681SAndroid Build Coastguard Worker // declarations of module-defined types do not have a file and line.
1620*9880d681SAndroid Build Coastguard Worker ByteSize = DIE->getAttributeValueAsUnsignedConstant(
1621*9880d681SAndroid Build Coastguard Worker &U.getOrigUnit(), dwarf::DW_AT_byte_size, UINT64_MAX);
1622*9880d681SAndroid Build Coastguard Worker if (Tag != dwarf::DW_TAG_namespace || !Name) {
1623*9880d681SAndroid Build Coastguard Worker if (unsigned FileNum = DIE->getAttributeValueAsUnsignedConstant(
1624*9880d681SAndroid Build Coastguard Worker &U.getOrigUnit(), dwarf::DW_AT_decl_file, 0)) {
1625*9880d681SAndroid Build Coastguard Worker if (const auto *LT = U.getOrigUnit().getContext().getLineTableForUnit(
1626*9880d681SAndroid Build Coastguard Worker &U.getOrigUnit())) {
1627*9880d681SAndroid Build Coastguard Worker // FIXME: dsymutil-classic compatibility. I'd rather not
1628*9880d681SAndroid Build Coastguard Worker // unique anything in anonymous namespaces, but if we do, then
1629*9880d681SAndroid Build Coastguard Worker // verify that the file and line correspond.
1630*9880d681SAndroid Build Coastguard Worker if (!Name && Tag == dwarf::DW_TAG_namespace)
1631*9880d681SAndroid Build Coastguard Worker FileNum = 1;
1632*9880d681SAndroid Build Coastguard Worker
1633*9880d681SAndroid Build Coastguard Worker // FIXME: Passing U.getOrigUnit().getCompilationDir()
1634*9880d681SAndroid Build Coastguard Worker // instead of "" would allow more uniquing, but for now, do
1635*9880d681SAndroid Build Coastguard Worker // it this way to match dsymutil-classic.
1636*9880d681SAndroid Build Coastguard Worker std::string File;
1637*9880d681SAndroid Build Coastguard Worker if (LT->getFileNameByIndex(
1638*9880d681SAndroid Build Coastguard Worker FileNum, "",
1639*9880d681SAndroid Build Coastguard Worker DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
1640*9880d681SAndroid Build Coastguard Worker File)) {
1641*9880d681SAndroid Build Coastguard Worker Line = DIE->getAttributeValueAsUnsignedConstant(
1642*9880d681SAndroid Build Coastguard Worker &U.getOrigUnit(), dwarf::DW_AT_decl_line, 0);
1643*9880d681SAndroid Build Coastguard Worker // Cache the resolved paths, because calling realpath is expansive.
1644*9880d681SAndroid Build Coastguard Worker StringRef ResolvedPath = U.getResolvedPath(FileNum);
1645*9880d681SAndroid Build Coastguard Worker if (!ResolvedPath.empty()) {
1646*9880d681SAndroid Build Coastguard Worker FileRef = ResolvedPath;
1647*9880d681SAndroid Build Coastguard Worker } else {
1648*9880d681SAndroid Build Coastguard Worker #ifdef HAVE_REALPATH
1649*9880d681SAndroid Build Coastguard Worker char RealPath[PATH_MAX + 1];
1650*9880d681SAndroid Build Coastguard Worker RealPath[PATH_MAX] = 0;
1651*9880d681SAndroid Build Coastguard Worker if (::realpath(File.c_str(), RealPath))
1652*9880d681SAndroid Build Coastguard Worker File = RealPath;
1653*9880d681SAndroid Build Coastguard Worker #endif
1654*9880d681SAndroid Build Coastguard Worker FileRef = StringPool.internString(File);
1655*9880d681SAndroid Build Coastguard Worker U.setResolvedPath(FileNum, FileRef);
1656*9880d681SAndroid Build Coastguard Worker }
1657*9880d681SAndroid Build Coastguard Worker }
1658*9880d681SAndroid Build Coastguard Worker }
1659*9880d681SAndroid Build Coastguard Worker }
1660*9880d681SAndroid Build Coastguard Worker }
1661*9880d681SAndroid Build Coastguard Worker }
1662*9880d681SAndroid Build Coastguard Worker
1663*9880d681SAndroid Build Coastguard Worker if (!Line && NameRef.empty())
1664*9880d681SAndroid Build Coastguard Worker return PointerIntPair<DeclContext *, 1>(nullptr);
1665*9880d681SAndroid Build Coastguard Worker
1666*9880d681SAndroid Build Coastguard Worker // We hash NameRef, which is the mangled name, in order to get most
1667*9880d681SAndroid Build Coastguard Worker // overloaded functions resolve correctly.
1668*9880d681SAndroid Build Coastguard Worker //
1669*9880d681SAndroid Build Coastguard Worker // Strictly speaking, hashing the Tag is only necessary for a
1670*9880d681SAndroid Build Coastguard Worker // DW_TAG_module, to prevent uniquing of a module and a namespace
1671*9880d681SAndroid Build Coastguard Worker // with the same name.
1672*9880d681SAndroid Build Coastguard Worker //
1673*9880d681SAndroid Build Coastguard Worker // FIXME: dsymutil-classic won't unique the same type presented
1674*9880d681SAndroid Build Coastguard Worker // once as a struct and once as a class. Using the Tag in the fully
1675*9880d681SAndroid Build Coastguard Worker // qualified name hash to get the same effect.
1676*9880d681SAndroid Build Coastguard Worker unsigned Hash = hash_combine(Context.getQualifiedNameHash(), Tag, NameRef);
1677*9880d681SAndroid Build Coastguard Worker
1678*9880d681SAndroid Build Coastguard Worker // FIXME: dsymutil-classic compatibility: when we don't have a name,
1679*9880d681SAndroid Build Coastguard Worker // use the filename.
1680*9880d681SAndroid Build Coastguard Worker if (Tag == dwarf::DW_TAG_namespace && NameRef == "(anonymous namespace)")
1681*9880d681SAndroid Build Coastguard Worker Hash = hash_combine(Hash, FileRef);
1682*9880d681SAndroid Build Coastguard Worker
1683*9880d681SAndroid Build Coastguard Worker // Now look if this context already exists.
1684*9880d681SAndroid Build Coastguard Worker DeclContext Key(Hash, Line, ByteSize, Tag, NameRef, FileRef, Context);
1685*9880d681SAndroid Build Coastguard Worker auto ContextIter = Contexts.find(&Key);
1686*9880d681SAndroid Build Coastguard Worker
1687*9880d681SAndroid Build Coastguard Worker if (ContextIter == Contexts.end()) {
1688*9880d681SAndroid Build Coastguard Worker // The context wasn't found.
1689*9880d681SAndroid Build Coastguard Worker bool Inserted;
1690*9880d681SAndroid Build Coastguard Worker DeclContext *NewContext =
1691*9880d681SAndroid Build Coastguard Worker new (Allocator) DeclContext(Hash, Line, ByteSize, Tag, NameRef, FileRef,
1692*9880d681SAndroid Build Coastguard Worker Context, DIE, U.getUniqueID());
1693*9880d681SAndroid Build Coastguard Worker std::tie(ContextIter, Inserted) = Contexts.insert(NewContext);
1694*9880d681SAndroid Build Coastguard Worker assert(Inserted && "Failed to insert DeclContext");
1695*9880d681SAndroid Build Coastguard Worker (void)Inserted;
1696*9880d681SAndroid Build Coastguard Worker } else if (Tag != dwarf::DW_TAG_namespace &&
1697*9880d681SAndroid Build Coastguard Worker !(*ContextIter)->setLastSeenDIE(U, DIE)) {
1698*9880d681SAndroid Build Coastguard Worker // The context was found, but it is ambiguous with another context
1699*9880d681SAndroid Build Coastguard Worker // in the same file. Mark it invalid.
1700*9880d681SAndroid Build Coastguard Worker return PointerIntPair<DeclContext *, 1>(*ContextIter, /* Invalid= */ 1);
1701*9880d681SAndroid Build Coastguard Worker }
1702*9880d681SAndroid Build Coastguard Worker
1703*9880d681SAndroid Build Coastguard Worker assert(ContextIter != Contexts.end());
1704*9880d681SAndroid Build Coastguard Worker // FIXME: dsymutil-classic compatibility. Union types aren't
1705*9880d681SAndroid Build Coastguard Worker // uniques, but their children might be.
1706*9880d681SAndroid Build Coastguard Worker if ((Tag == dwarf::DW_TAG_subprogram &&
1707*9880d681SAndroid Build Coastguard Worker Context.getTag() != dwarf::DW_TAG_structure_type &&
1708*9880d681SAndroid Build Coastguard Worker Context.getTag() != dwarf::DW_TAG_class_type) ||
1709*9880d681SAndroid Build Coastguard Worker (Tag == dwarf::DW_TAG_union_type))
1710*9880d681SAndroid Build Coastguard Worker return PointerIntPair<DeclContext *, 1>(*ContextIter, /* Invalid= */ 1);
1711*9880d681SAndroid Build Coastguard Worker
1712*9880d681SAndroid Build Coastguard Worker return PointerIntPair<DeclContext *, 1>(*ContextIter);
1713*9880d681SAndroid Build Coastguard Worker }
1714*9880d681SAndroid Build Coastguard Worker
getDIENames(const DWARFDebugInfoEntryMinimal & Die,DWARFUnit & U,AttributesInfo & Info)1715*9880d681SAndroid Build Coastguard Worker bool DwarfLinker::DIECloner::getDIENames(const DWARFDebugInfoEntryMinimal &Die,
1716*9880d681SAndroid Build Coastguard Worker DWARFUnit &U, AttributesInfo &Info) {
1717*9880d681SAndroid Build Coastguard Worker // FIXME: a bit wasteful as the first getName might return the
1718*9880d681SAndroid Build Coastguard Worker // short name.
1719*9880d681SAndroid Build Coastguard Worker if (!Info.MangledName &&
1720*9880d681SAndroid Build Coastguard Worker (Info.MangledName = Die.getName(&U, DINameKind::LinkageName)))
1721*9880d681SAndroid Build Coastguard Worker Info.MangledNameOffset =
1722*9880d681SAndroid Build Coastguard Worker Linker.StringPool.getStringOffset(Info.MangledName);
1723*9880d681SAndroid Build Coastguard Worker
1724*9880d681SAndroid Build Coastguard Worker if (!Info.Name && (Info.Name = Die.getName(&U, DINameKind::ShortName)))
1725*9880d681SAndroid Build Coastguard Worker Info.NameOffset = Linker.StringPool.getStringOffset(Info.Name);
1726*9880d681SAndroid Build Coastguard Worker
1727*9880d681SAndroid Build Coastguard Worker return Info.Name || Info.MangledName;
1728*9880d681SAndroid Build Coastguard Worker }
1729*9880d681SAndroid Build Coastguard Worker
1730*9880d681SAndroid Build Coastguard Worker /// \brief Report a warning to the user, optionaly including
1731*9880d681SAndroid Build Coastguard Worker /// information about a specific \p DIE related to the warning.
reportWarning(const Twine & Warning,const DWARFUnit * Unit,const DWARFDebugInfoEntryMinimal * DIE) const1732*9880d681SAndroid Build Coastguard Worker void DwarfLinker::reportWarning(const Twine &Warning, const DWARFUnit *Unit,
1733*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal *DIE) const {
1734*9880d681SAndroid Build Coastguard Worker StringRef Context = "<debug map>";
1735*9880d681SAndroid Build Coastguard Worker if (CurrentDebugObject)
1736*9880d681SAndroid Build Coastguard Worker Context = CurrentDebugObject->getObjectFilename();
1737*9880d681SAndroid Build Coastguard Worker warn(Warning, Context);
1738*9880d681SAndroid Build Coastguard Worker
1739*9880d681SAndroid Build Coastguard Worker if (!Options.Verbose || !DIE)
1740*9880d681SAndroid Build Coastguard Worker return;
1741*9880d681SAndroid Build Coastguard Worker
1742*9880d681SAndroid Build Coastguard Worker errs() << " in DIE:\n";
1743*9880d681SAndroid Build Coastguard Worker DIE->dump(errs(), const_cast<DWARFUnit *>(Unit), 0 /* RecurseDepth */,
1744*9880d681SAndroid Build Coastguard Worker 6 /* Indent */);
1745*9880d681SAndroid Build Coastguard Worker }
1746*9880d681SAndroid Build Coastguard Worker
createStreamer(const Triple & TheTriple,StringRef OutputFilename)1747*9880d681SAndroid Build Coastguard Worker bool DwarfLinker::createStreamer(const Triple &TheTriple,
1748*9880d681SAndroid Build Coastguard Worker StringRef OutputFilename) {
1749*9880d681SAndroid Build Coastguard Worker if (Options.NoOutput)
1750*9880d681SAndroid Build Coastguard Worker return true;
1751*9880d681SAndroid Build Coastguard Worker
1752*9880d681SAndroid Build Coastguard Worker Streamer = llvm::make_unique<DwarfStreamer>();
1753*9880d681SAndroid Build Coastguard Worker return Streamer->init(TheTriple, OutputFilename);
1754*9880d681SAndroid Build Coastguard Worker }
1755*9880d681SAndroid Build Coastguard Worker
1756*9880d681SAndroid Build Coastguard Worker /// Recursive helper to build the global DeclContext information and
1757*9880d681SAndroid Build Coastguard Worker /// gather the child->parent relationships in the original compile unit.
1758*9880d681SAndroid Build Coastguard Worker ///
1759*9880d681SAndroid Build Coastguard Worker /// \return true when this DIE and all of its children are only
1760*9880d681SAndroid Build Coastguard Worker /// forward declarations to types defined in external clang modules
1761*9880d681SAndroid Build Coastguard Worker /// (i.e., forward declarations that are children of a DW_TAG_module).
analyzeContextInfo(const DWARFDebugInfoEntryMinimal * DIE,unsigned ParentIdx,CompileUnit & CU,DeclContext * CurrentDeclContext,NonRelocatableStringpool & StringPool,DeclContextTree & Contexts,bool InImportedModule=false)1762*9880d681SAndroid Build Coastguard Worker static bool analyzeContextInfo(const DWARFDebugInfoEntryMinimal *DIE,
1763*9880d681SAndroid Build Coastguard Worker unsigned ParentIdx, CompileUnit &CU,
1764*9880d681SAndroid Build Coastguard Worker DeclContext *CurrentDeclContext,
1765*9880d681SAndroid Build Coastguard Worker NonRelocatableStringpool &StringPool,
1766*9880d681SAndroid Build Coastguard Worker DeclContextTree &Contexts,
1767*9880d681SAndroid Build Coastguard Worker bool InImportedModule = false) {
1768*9880d681SAndroid Build Coastguard Worker unsigned MyIdx = CU.getOrigUnit().getDIEIndex(DIE);
1769*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &Info = CU.getInfo(MyIdx);
1770*9880d681SAndroid Build Coastguard Worker
1771*9880d681SAndroid Build Coastguard Worker // Clang imposes an ODR on modules(!) regardless of the language:
1772*9880d681SAndroid Build Coastguard Worker // "The module-id should consist of only a single identifier,
1773*9880d681SAndroid Build Coastguard Worker // which provides the name of the module being defined. Each
1774*9880d681SAndroid Build Coastguard Worker // module shall have a single definition."
1775*9880d681SAndroid Build Coastguard Worker //
1776*9880d681SAndroid Build Coastguard Worker // This does not extend to the types inside the modules:
1777*9880d681SAndroid Build Coastguard Worker // "[I]n C, this implies that if two structs are defined in
1778*9880d681SAndroid Build Coastguard Worker // different submodules with the same name, those two types are
1779*9880d681SAndroid Build Coastguard Worker // distinct types (but may be compatible types if their
1780*9880d681SAndroid Build Coastguard Worker // definitions match)."
1781*9880d681SAndroid Build Coastguard Worker //
1782*9880d681SAndroid Build Coastguard Worker // We treat non-C++ modules like namespaces for this reason.
1783*9880d681SAndroid Build Coastguard Worker if (DIE->getTag() == dwarf::DW_TAG_module && ParentIdx == 0 &&
1784*9880d681SAndroid Build Coastguard Worker DIE->getAttributeValueAsString(&CU.getOrigUnit(), dwarf::DW_AT_name,
1785*9880d681SAndroid Build Coastguard Worker "") != CU.getClangModuleName()) {
1786*9880d681SAndroid Build Coastguard Worker InImportedModule = true;
1787*9880d681SAndroid Build Coastguard Worker }
1788*9880d681SAndroid Build Coastguard Worker
1789*9880d681SAndroid Build Coastguard Worker Info.ParentIdx = ParentIdx;
1790*9880d681SAndroid Build Coastguard Worker bool InClangModule = CU.isClangModule() || InImportedModule;
1791*9880d681SAndroid Build Coastguard Worker if (CU.hasODR() || InClangModule) {
1792*9880d681SAndroid Build Coastguard Worker if (CurrentDeclContext) {
1793*9880d681SAndroid Build Coastguard Worker auto PtrInvalidPair = Contexts.getChildDeclContext(
1794*9880d681SAndroid Build Coastguard Worker *CurrentDeclContext, DIE, CU, StringPool, InClangModule);
1795*9880d681SAndroid Build Coastguard Worker CurrentDeclContext = PtrInvalidPair.getPointer();
1796*9880d681SAndroid Build Coastguard Worker Info.Ctxt =
1797*9880d681SAndroid Build Coastguard Worker PtrInvalidPair.getInt() ? nullptr : PtrInvalidPair.getPointer();
1798*9880d681SAndroid Build Coastguard Worker } else
1799*9880d681SAndroid Build Coastguard Worker Info.Ctxt = CurrentDeclContext = nullptr;
1800*9880d681SAndroid Build Coastguard Worker }
1801*9880d681SAndroid Build Coastguard Worker
1802*9880d681SAndroid Build Coastguard Worker Info.Prune = InImportedModule;
1803*9880d681SAndroid Build Coastguard Worker if (DIE->hasChildren())
1804*9880d681SAndroid Build Coastguard Worker for (auto *Child = DIE->getFirstChild(); Child && !Child->isNULL();
1805*9880d681SAndroid Build Coastguard Worker Child = Child->getSibling())
1806*9880d681SAndroid Build Coastguard Worker Info.Prune &= analyzeContextInfo(Child, MyIdx, CU, CurrentDeclContext,
1807*9880d681SAndroid Build Coastguard Worker StringPool, Contexts, InImportedModule);
1808*9880d681SAndroid Build Coastguard Worker
1809*9880d681SAndroid Build Coastguard Worker // Prune this DIE if it is either a forward declaration inside a
1810*9880d681SAndroid Build Coastguard Worker // DW_TAG_module or a DW_TAG_module that contains nothing but
1811*9880d681SAndroid Build Coastguard Worker // forward declarations.
1812*9880d681SAndroid Build Coastguard Worker Info.Prune &= (DIE->getTag() == dwarf::DW_TAG_module) ||
1813*9880d681SAndroid Build Coastguard Worker DIE->getAttributeValueAsUnsignedConstant(
1814*9880d681SAndroid Build Coastguard Worker &CU.getOrigUnit(), dwarf::DW_AT_declaration, 0);
1815*9880d681SAndroid Build Coastguard Worker
1816*9880d681SAndroid Build Coastguard Worker // Don't prune it if there is no definition for the DIE.
1817*9880d681SAndroid Build Coastguard Worker Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset();
1818*9880d681SAndroid Build Coastguard Worker
1819*9880d681SAndroid Build Coastguard Worker return Info.Prune;
1820*9880d681SAndroid Build Coastguard Worker }
1821*9880d681SAndroid Build Coastguard Worker
dieNeedsChildrenToBeMeaningful(uint32_t Tag)1822*9880d681SAndroid Build Coastguard Worker static bool dieNeedsChildrenToBeMeaningful(uint32_t Tag) {
1823*9880d681SAndroid Build Coastguard Worker switch (Tag) {
1824*9880d681SAndroid Build Coastguard Worker default:
1825*9880d681SAndroid Build Coastguard Worker return false;
1826*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_subprogram:
1827*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_lexical_block:
1828*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_subroutine_type:
1829*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_structure_type:
1830*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_class_type:
1831*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_union_type:
1832*9880d681SAndroid Build Coastguard Worker return true;
1833*9880d681SAndroid Build Coastguard Worker }
1834*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid Tag");
1835*9880d681SAndroid Build Coastguard Worker }
1836*9880d681SAndroid Build Coastguard Worker
getRefAddrSize(const DWARFUnit & U)1837*9880d681SAndroid Build Coastguard Worker static unsigned getRefAddrSize(const DWARFUnit &U) {
1838*9880d681SAndroid Build Coastguard Worker if (U.getVersion() == 2)
1839*9880d681SAndroid Build Coastguard Worker return U.getAddressByteSize();
1840*9880d681SAndroid Build Coastguard Worker return 4;
1841*9880d681SAndroid Build Coastguard Worker }
1842*9880d681SAndroid Build Coastguard Worker
startDebugObject(DWARFContext & Dwarf,DebugMapObject & Obj)1843*9880d681SAndroid Build Coastguard Worker void DwarfLinker::startDebugObject(DWARFContext &Dwarf, DebugMapObject &Obj) {
1844*9880d681SAndroid Build Coastguard Worker Units.reserve(Dwarf.getNumCompileUnits());
1845*9880d681SAndroid Build Coastguard Worker // Iterate over the debug map entries and put all the ones that are
1846*9880d681SAndroid Build Coastguard Worker // functions (because they have a size) into the Ranges map. This
1847*9880d681SAndroid Build Coastguard Worker // map is very similar to the FunctionRanges that are stored in each
1848*9880d681SAndroid Build Coastguard Worker // unit, with 2 notable differences:
1849*9880d681SAndroid Build Coastguard Worker // - obviously this one is global, while the other ones are per-unit.
1850*9880d681SAndroid Build Coastguard Worker // - this one contains not only the functions described in the DIE
1851*9880d681SAndroid Build Coastguard Worker // tree, but also the ones that are only in the debug map.
1852*9880d681SAndroid Build Coastguard Worker // The latter information is required to reproduce dsymutil's logic
1853*9880d681SAndroid Build Coastguard Worker // while linking line tables. The cases where this information
1854*9880d681SAndroid Build Coastguard Worker // matters look like bugs that need to be investigated, but for now
1855*9880d681SAndroid Build Coastguard Worker // we need to reproduce dsymutil's behavior.
1856*9880d681SAndroid Build Coastguard Worker // FIXME: Once we understood exactly if that information is needed,
1857*9880d681SAndroid Build Coastguard Worker // maybe totally remove this (or try to use it to do a real
1858*9880d681SAndroid Build Coastguard Worker // -gline-tables-only on Darwin.
1859*9880d681SAndroid Build Coastguard Worker for (const auto &Entry : Obj.symbols()) {
1860*9880d681SAndroid Build Coastguard Worker const auto &Mapping = Entry.getValue();
1861*9880d681SAndroid Build Coastguard Worker if (Mapping.Size && Mapping.ObjectAddress)
1862*9880d681SAndroid Build Coastguard Worker Ranges[*Mapping.ObjectAddress] = std::make_pair(
1863*9880d681SAndroid Build Coastguard Worker *Mapping.ObjectAddress + Mapping.Size,
1864*9880d681SAndroid Build Coastguard Worker int64_t(Mapping.BinaryAddress) - *Mapping.ObjectAddress);
1865*9880d681SAndroid Build Coastguard Worker }
1866*9880d681SAndroid Build Coastguard Worker }
1867*9880d681SAndroid Build Coastguard Worker
endDebugObject()1868*9880d681SAndroid Build Coastguard Worker void DwarfLinker::endDebugObject() {
1869*9880d681SAndroid Build Coastguard Worker Units.clear();
1870*9880d681SAndroid Build Coastguard Worker Ranges.clear();
1871*9880d681SAndroid Build Coastguard Worker
1872*9880d681SAndroid Build Coastguard Worker for (auto I = DIEBlocks.begin(), E = DIEBlocks.end(); I != E; ++I)
1873*9880d681SAndroid Build Coastguard Worker (*I)->~DIEBlock();
1874*9880d681SAndroid Build Coastguard Worker for (auto I = DIELocs.begin(), E = DIELocs.end(); I != E; ++I)
1875*9880d681SAndroid Build Coastguard Worker (*I)->~DIELoc();
1876*9880d681SAndroid Build Coastguard Worker
1877*9880d681SAndroid Build Coastguard Worker DIEBlocks.clear();
1878*9880d681SAndroid Build Coastguard Worker DIELocs.clear();
1879*9880d681SAndroid Build Coastguard Worker DIEAlloc.Reset();
1880*9880d681SAndroid Build Coastguard Worker }
1881*9880d681SAndroid Build Coastguard Worker
isMachOPairedReloc(uint64_t RelocType,uint64_t Arch)1882*9880d681SAndroid Build Coastguard Worker static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) {
1883*9880d681SAndroid Build Coastguard Worker switch (Arch) {
1884*9880d681SAndroid Build Coastguard Worker case Triple::x86:
1885*9880d681SAndroid Build Coastguard Worker return RelocType == MachO::GENERIC_RELOC_SECTDIFF ||
1886*9880d681SAndroid Build Coastguard Worker RelocType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF;
1887*9880d681SAndroid Build Coastguard Worker case Triple::x86_64:
1888*9880d681SAndroid Build Coastguard Worker return RelocType == MachO::X86_64_RELOC_SUBTRACTOR;
1889*9880d681SAndroid Build Coastguard Worker case Triple::arm:
1890*9880d681SAndroid Build Coastguard Worker case Triple::thumb:
1891*9880d681SAndroid Build Coastguard Worker return RelocType == MachO::ARM_RELOC_SECTDIFF ||
1892*9880d681SAndroid Build Coastguard Worker RelocType == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
1893*9880d681SAndroid Build Coastguard Worker RelocType == MachO::ARM_RELOC_HALF ||
1894*9880d681SAndroid Build Coastguard Worker RelocType == MachO::ARM_RELOC_HALF_SECTDIFF;
1895*9880d681SAndroid Build Coastguard Worker case Triple::aarch64:
1896*9880d681SAndroid Build Coastguard Worker return RelocType == MachO::ARM64_RELOC_SUBTRACTOR;
1897*9880d681SAndroid Build Coastguard Worker default:
1898*9880d681SAndroid Build Coastguard Worker return false;
1899*9880d681SAndroid Build Coastguard Worker }
1900*9880d681SAndroid Build Coastguard Worker }
1901*9880d681SAndroid Build Coastguard Worker
1902*9880d681SAndroid Build Coastguard Worker /// \brief Iterate over the relocations of the given \p Section and
1903*9880d681SAndroid Build Coastguard Worker /// store the ones that correspond to debug map entries into the
1904*9880d681SAndroid Build Coastguard Worker /// ValidRelocs array.
1905*9880d681SAndroid Build Coastguard Worker void DwarfLinker::RelocationManager::
findValidRelocsMachO(const object::SectionRef & Section,const object::MachOObjectFile & Obj,const DebugMapObject & DMO)1906*9880d681SAndroid Build Coastguard Worker findValidRelocsMachO(const object::SectionRef &Section,
1907*9880d681SAndroid Build Coastguard Worker const object::MachOObjectFile &Obj,
1908*9880d681SAndroid Build Coastguard Worker const DebugMapObject &DMO) {
1909*9880d681SAndroid Build Coastguard Worker StringRef Contents;
1910*9880d681SAndroid Build Coastguard Worker Section.getContents(Contents);
1911*9880d681SAndroid Build Coastguard Worker DataExtractor Data(Contents, Obj.isLittleEndian(), 0);
1912*9880d681SAndroid Build Coastguard Worker bool SkipNext = false;
1913*9880d681SAndroid Build Coastguard Worker
1914*9880d681SAndroid Build Coastguard Worker for (const object::RelocationRef &Reloc : Section.relocations()) {
1915*9880d681SAndroid Build Coastguard Worker if (SkipNext) {
1916*9880d681SAndroid Build Coastguard Worker SkipNext = false;
1917*9880d681SAndroid Build Coastguard Worker continue;
1918*9880d681SAndroid Build Coastguard Worker }
1919*9880d681SAndroid Build Coastguard Worker
1920*9880d681SAndroid Build Coastguard Worker object::DataRefImpl RelocDataRef = Reloc.getRawDataRefImpl();
1921*9880d681SAndroid Build Coastguard Worker MachO::any_relocation_info MachOReloc = Obj.getRelocation(RelocDataRef);
1922*9880d681SAndroid Build Coastguard Worker
1923*9880d681SAndroid Build Coastguard Worker if (isMachOPairedReloc(Obj.getAnyRelocationType(MachOReloc),
1924*9880d681SAndroid Build Coastguard Worker Obj.getArch())) {
1925*9880d681SAndroid Build Coastguard Worker SkipNext = true;
1926*9880d681SAndroid Build Coastguard Worker Linker.reportWarning(" unsupported relocation in debug_info section.");
1927*9880d681SAndroid Build Coastguard Worker continue;
1928*9880d681SAndroid Build Coastguard Worker }
1929*9880d681SAndroid Build Coastguard Worker
1930*9880d681SAndroid Build Coastguard Worker unsigned RelocSize = 1 << Obj.getAnyRelocationLength(MachOReloc);
1931*9880d681SAndroid Build Coastguard Worker uint64_t Offset64 = Reloc.getOffset();
1932*9880d681SAndroid Build Coastguard Worker if ((RelocSize != 4 && RelocSize != 8)) {
1933*9880d681SAndroid Build Coastguard Worker Linker.reportWarning(" unsupported relocation in debug_info section.");
1934*9880d681SAndroid Build Coastguard Worker continue;
1935*9880d681SAndroid Build Coastguard Worker }
1936*9880d681SAndroid Build Coastguard Worker uint32_t Offset = Offset64;
1937*9880d681SAndroid Build Coastguard Worker // Mach-o uses REL relocations, the addend is at the relocation offset.
1938*9880d681SAndroid Build Coastguard Worker uint64_t Addend = Data.getUnsigned(&Offset, RelocSize);
1939*9880d681SAndroid Build Coastguard Worker uint64_t SymAddress;
1940*9880d681SAndroid Build Coastguard Worker int64_t SymOffset;
1941*9880d681SAndroid Build Coastguard Worker
1942*9880d681SAndroid Build Coastguard Worker if (Obj.isRelocationScattered(MachOReloc)) {
1943*9880d681SAndroid Build Coastguard Worker // The address of the base symbol for scattered relocations is
1944*9880d681SAndroid Build Coastguard Worker // stored in the reloc itself. The actual addend will store the
1945*9880d681SAndroid Build Coastguard Worker // base address plus the offset.
1946*9880d681SAndroid Build Coastguard Worker SymAddress = Obj.getScatteredRelocationValue(MachOReloc);
1947*9880d681SAndroid Build Coastguard Worker SymOffset = int64_t(Addend) - SymAddress;
1948*9880d681SAndroid Build Coastguard Worker } else {
1949*9880d681SAndroid Build Coastguard Worker SymAddress = Addend;
1950*9880d681SAndroid Build Coastguard Worker SymOffset = 0;
1951*9880d681SAndroid Build Coastguard Worker }
1952*9880d681SAndroid Build Coastguard Worker
1953*9880d681SAndroid Build Coastguard Worker auto Sym = Reloc.getSymbol();
1954*9880d681SAndroid Build Coastguard Worker if (Sym != Obj.symbol_end()) {
1955*9880d681SAndroid Build Coastguard Worker Expected<StringRef> SymbolName = Sym->getName();
1956*9880d681SAndroid Build Coastguard Worker if (!SymbolName) {
1957*9880d681SAndroid Build Coastguard Worker consumeError(SymbolName.takeError());
1958*9880d681SAndroid Build Coastguard Worker Linker.reportWarning("error getting relocation symbol name.");
1959*9880d681SAndroid Build Coastguard Worker continue;
1960*9880d681SAndroid Build Coastguard Worker }
1961*9880d681SAndroid Build Coastguard Worker if (const auto *Mapping = DMO.lookupSymbol(*SymbolName))
1962*9880d681SAndroid Build Coastguard Worker ValidRelocs.emplace_back(Offset64, RelocSize, Addend, Mapping);
1963*9880d681SAndroid Build Coastguard Worker } else if (const auto *Mapping = DMO.lookupObjectAddress(SymAddress)) {
1964*9880d681SAndroid Build Coastguard Worker // Do not store the addend. The addend was the address of the
1965*9880d681SAndroid Build Coastguard Worker // symbol in the object file, the address in the binary that is
1966*9880d681SAndroid Build Coastguard Worker // stored in the debug map doesn't need to be offseted.
1967*9880d681SAndroid Build Coastguard Worker ValidRelocs.emplace_back(Offset64, RelocSize, SymOffset, Mapping);
1968*9880d681SAndroid Build Coastguard Worker }
1969*9880d681SAndroid Build Coastguard Worker }
1970*9880d681SAndroid Build Coastguard Worker }
1971*9880d681SAndroid Build Coastguard Worker
1972*9880d681SAndroid Build Coastguard Worker /// \brief Dispatch the valid relocation finding logic to the
1973*9880d681SAndroid Build Coastguard Worker /// appropriate handler depending on the object file format.
findValidRelocs(const object::SectionRef & Section,const object::ObjectFile & Obj,const DebugMapObject & DMO)1974*9880d681SAndroid Build Coastguard Worker bool DwarfLinker::RelocationManager::findValidRelocs(
1975*9880d681SAndroid Build Coastguard Worker const object::SectionRef &Section, const object::ObjectFile &Obj,
1976*9880d681SAndroid Build Coastguard Worker const DebugMapObject &DMO) {
1977*9880d681SAndroid Build Coastguard Worker // Dispatch to the right handler depending on the file type.
1978*9880d681SAndroid Build Coastguard Worker if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(&Obj))
1979*9880d681SAndroid Build Coastguard Worker findValidRelocsMachO(Section, *MachOObj, DMO);
1980*9880d681SAndroid Build Coastguard Worker else
1981*9880d681SAndroid Build Coastguard Worker Linker.reportWarning(Twine("unsupported object file type: ") +
1982*9880d681SAndroid Build Coastguard Worker Obj.getFileName());
1983*9880d681SAndroid Build Coastguard Worker
1984*9880d681SAndroid Build Coastguard Worker if (ValidRelocs.empty())
1985*9880d681SAndroid Build Coastguard Worker return false;
1986*9880d681SAndroid Build Coastguard Worker
1987*9880d681SAndroid Build Coastguard Worker // Sort the relocations by offset. We will walk the DIEs linearly in
1988*9880d681SAndroid Build Coastguard Worker // the file, this allows us to just keep an index in the relocation
1989*9880d681SAndroid Build Coastguard Worker // array that we advance during our walk, rather than resorting to
1990*9880d681SAndroid Build Coastguard Worker // some associative container. See DwarfLinker::NextValidReloc.
1991*9880d681SAndroid Build Coastguard Worker std::sort(ValidRelocs.begin(), ValidRelocs.end());
1992*9880d681SAndroid Build Coastguard Worker return true;
1993*9880d681SAndroid Build Coastguard Worker }
1994*9880d681SAndroid Build Coastguard Worker
1995*9880d681SAndroid Build Coastguard Worker /// \brief Look for relocations in the debug_info section that match
1996*9880d681SAndroid Build Coastguard Worker /// entries in the debug map. These relocations will drive the Dwarf
1997*9880d681SAndroid Build Coastguard Worker /// link by indicating which DIEs refer to symbols present in the
1998*9880d681SAndroid Build Coastguard Worker /// linked binary.
1999*9880d681SAndroid Build Coastguard Worker /// \returns wether there are any valid relocations in the debug info.
2000*9880d681SAndroid Build Coastguard Worker bool DwarfLinker::RelocationManager::
findValidRelocsInDebugInfo(const object::ObjectFile & Obj,const DebugMapObject & DMO)2001*9880d681SAndroid Build Coastguard Worker findValidRelocsInDebugInfo(const object::ObjectFile &Obj,
2002*9880d681SAndroid Build Coastguard Worker const DebugMapObject &DMO) {
2003*9880d681SAndroid Build Coastguard Worker // Find the debug_info section.
2004*9880d681SAndroid Build Coastguard Worker for (const object::SectionRef &Section : Obj.sections()) {
2005*9880d681SAndroid Build Coastguard Worker StringRef SectionName;
2006*9880d681SAndroid Build Coastguard Worker Section.getName(SectionName);
2007*9880d681SAndroid Build Coastguard Worker SectionName = SectionName.substr(SectionName.find_first_not_of("._"));
2008*9880d681SAndroid Build Coastguard Worker if (SectionName != "debug_info")
2009*9880d681SAndroid Build Coastguard Worker continue;
2010*9880d681SAndroid Build Coastguard Worker return findValidRelocs(Section, Obj, DMO);
2011*9880d681SAndroid Build Coastguard Worker }
2012*9880d681SAndroid Build Coastguard Worker return false;
2013*9880d681SAndroid Build Coastguard Worker }
2014*9880d681SAndroid Build Coastguard Worker
2015*9880d681SAndroid Build Coastguard Worker /// \brief Checks that there is a relocation against an actual debug
2016*9880d681SAndroid Build Coastguard Worker /// map entry between \p StartOffset and \p NextOffset.
2017*9880d681SAndroid Build Coastguard Worker ///
2018*9880d681SAndroid Build Coastguard Worker /// This function must be called with offsets in strictly ascending
2019*9880d681SAndroid Build Coastguard Worker /// order because it never looks back at relocations it already 'went past'.
2020*9880d681SAndroid Build Coastguard Worker /// \returns true and sets Info.InDebugMap if it is the case.
2021*9880d681SAndroid Build Coastguard Worker bool DwarfLinker::RelocationManager::
hasValidRelocation(uint32_t StartOffset,uint32_t EndOffset,CompileUnit::DIEInfo & Info)2022*9880d681SAndroid Build Coastguard Worker hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset,
2023*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &Info) {
2024*9880d681SAndroid Build Coastguard Worker assert(NextValidReloc == 0 ||
2025*9880d681SAndroid Build Coastguard Worker StartOffset > ValidRelocs[NextValidReloc - 1].Offset);
2026*9880d681SAndroid Build Coastguard Worker if (NextValidReloc >= ValidRelocs.size())
2027*9880d681SAndroid Build Coastguard Worker return false;
2028*9880d681SAndroid Build Coastguard Worker
2029*9880d681SAndroid Build Coastguard Worker uint64_t RelocOffset = ValidRelocs[NextValidReloc].Offset;
2030*9880d681SAndroid Build Coastguard Worker
2031*9880d681SAndroid Build Coastguard Worker // We might need to skip some relocs that we didn't consider. For
2032*9880d681SAndroid Build Coastguard Worker // example the high_pc of a discarded DIE might contain a reloc that
2033*9880d681SAndroid Build Coastguard Worker // is in the list because it actually corresponds to the start of a
2034*9880d681SAndroid Build Coastguard Worker // function that is in the debug map.
2035*9880d681SAndroid Build Coastguard Worker while (RelocOffset < StartOffset && NextValidReloc < ValidRelocs.size() - 1)
2036*9880d681SAndroid Build Coastguard Worker RelocOffset = ValidRelocs[++NextValidReloc].Offset;
2037*9880d681SAndroid Build Coastguard Worker
2038*9880d681SAndroid Build Coastguard Worker if (RelocOffset < StartOffset || RelocOffset >= EndOffset)
2039*9880d681SAndroid Build Coastguard Worker return false;
2040*9880d681SAndroid Build Coastguard Worker
2041*9880d681SAndroid Build Coastguard Worker const auto &ValidReloc = ValidRelocs[NextValidReloc++];
2042*9880d681SAndroid Build Coastguard Worker const auto &Mapping = ValidReloc.Mapping->getValue();
2043*9880d681SAndroid Build Coastguard Worker uint64_t ObjectAddress =
2044*9880d681SAndroid Build Coastguard Worker Mapping.ObjectAddress ? uint64_t(*Mapping.ObjectAddress) : UINT64_MAX;
2045*9880d681SAndroid Build Coastguard Worker if (Linker.Options.Verbose)
2046*9880d681SAndroid Build Coastguard Worker outs() << "Found valid debug map entry: " << ValidReloc.Mapping->getKey()
2047*9880d681SAndroid Build Coastguard Worker << " " << format("\t%016" PRIx64 " => %016" PRIx64, ObjectAddress,
2048*9880d681SAndroid Build Coastguard Worker uint64_t(Mapping.BinaryAddress));
2049*9880d681SAndroid Build Coastguard Worker
2050*9880d681SAndroid Build Coastguard Worker Info.AddrAdjust = int64_t(Mapping.BinaryAddress) + ValidReloc.Addend;
2051*9880d681SAndroid Build Coastguard Worker if (Mapping.ObjectAddress)
2052*9880d681SAndroid Build Coastguard Worker Info.AddrAdjust -= ObjectAddress;
2053*9880d681SAndroid Build Coastguard Worker Info.InDebugMap = true;
2054*9880d681SAndroid Build Coastguard Worker return true;
2055*9880d681SAndroid Build Coastguard Worker }
2056*9880d681SAndroid Build Coastguard Worker
2057*9880d681SAndroid Build Coastguard Worker /// \brief Get the starting and ending (exclusive) offset for the
2058*9880d681SAndroid Build Coastguard Worker /// attribute with index \p Idx descibed by \p Abbrev. \p Offset is
2059*9880d681SAndroid Build Coastguard Worker /// supposed to point to the position of the first attribute described
2060*9880d681SAndroid Build Coastguard Worker /// by \p Abbrev.
2061*9880d681SAndroid Build Coastguard Worker /// \return [StartOffset, EndOffset) as a pair.
2062*9880d681SAndroid Build Coastguard Worker static std::pair<uint32_t, uint32_t>
getAttributeOffsets(const DWARFAbbreviationDeclaration * Abbrev,unsigned Idx,unsigned Offset,const DWARFUnit & Unit)2063*9880d681SAndroid Build Coastguard Worker getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx,
2064*9880d681SAndroid Build Coastguard Worker unsigned Offset, const DWARFUnit &Unit) {
2065*9880d681SAndroid Build Coastguard Worker DataExtractor Data = Unit.getDebugInfoExtractor();
2066*9880d681SAndroid Build Coastguard Worker
2067*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < Idx; ++i)
2068*9880d681SAndroid Build Coastguard Worker DWARFFormValue::skipValue(Abbrev->getFormByIndex(i), Data, &Offset, &Unit);
2069*9880d681SAndroid Build Coastguard Worker
2070*9880d681SAndroid Build Coastguard Worker uint32_t End = Offset;
2071*9880d681SAndroid Build Coastguard Worker DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End, &Unit);
2072*9880d681SAndroid Build Coastguard Worker
2073*9880d681SAndroid Build Coastguard Worker return std::make_pair(Offset, End);
2074*9880d681SAndroid Build Coastguard Worker }
2075*9880d681SAndroid Build Coastguard Worker
2076*9880d681SAndroid Build Coastguard Worker /// \brief Check if a variable describing DIE should be kept.
2077*9880d681SAndroid Build Coastguard Worker /// \returns updated TraversalFlags.
shouldKeepVariableDIE(RelocationManager & RelocMgr,const DWARFDebugInfoEntryMinimal & DIE,CompileUnit & Unit,CompileUnit::DIEInfo & MyInfo,unsigned Flags)2078*9880d681SAndroid Build Coastguard Worker unsigned DwarfLinker::shouldKeepVariableDIE(RelocationManager &RelocMgr,
2079*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &DIE,
2080*9880d681SAndroid Build Coastguard Worker CompileUnit &Unit,
2081*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &MyInfo,
2082*9880d681SAndroid Build Coastguard Worker unsigned Flags) {
2083*9880d681SAndroid Build Coastguard Worker const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
2084*9880d681SAndroid Build Coastguard Worker
2085*9880d681SAndroid Build Coastguard Worker // Global variables with constant value can always be kept.
2086*9880d681SAndroid Build Coastguard Worker if (!(Flags & TF_InFunctionScope) &&
2087*9880d681SAndroid Build Coastguard Worker Abbrev->findAttributeIndex(dwarf::DW_AT_const_value) != -1U) {
2088*9880d681SAndroid Build Coastguard Worker MyInfo.InDebugMap = true;
2089*9880d681SAndroid Build Coastguard Worker return Flags | TF_Keep;
2090*9880d681SAndroid Build Coastguard Worker }
2091*9880d681SAndroid Build Coastguard Worker
2092*9880d681SAndroid Build Coastguard Worker uint32_t LocationIdx = Abbrev->findAttributeIndex(dwarf::DW_AT_location);
2093*9880d681SAndroid Build Coastguard Worker if (LocationIdx == -1U)
2094*9880d681SAndroid Build Coastguard Worker return Flags;
2095*9880d681SAndroid Build Coastguard Worker
2096*9880d681SAndroid Build Coastguard Worker uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
2097*9880d681SAndroid Build Coastguard Worker const DWARFUnit &OrigUnit = Unit.getOrigUnit();
2098*9880d681SAndroid Build Coastguard Worker uint32_t LocationOffset, LocationEndOffset;
2099*9880d681SAndroid Build Coastguard Worker std::tie(LocationOffset, LocationEndOffset) =
2100*9880d681SAndroid Build Coastguard Worker getAttributeOffsets(Abbrev, LocationIdx, Offset, OrigUnit);
2101*9880d681SAndroid Build Coastguard Worker
2102*9880d681SAndroid Build Coastguard Worker // See if there is a relocation to a valid debug map entry inside
2103*9880d681SAndroid Build Coastguard Worker // this variable's location. The order is important here. We want to
2104*9880d681SAndroid Build Coastguard Worker // always check in the variable has a valid relocation, so that the
2105*9880d681SAndroid Build Coastguard Worker // DIEInfo is filled. However, we don't want a static variable in a
2106*9880d681SAndroid Build Coastguard Worker // function to force us to keep the enclosing function.
2107*9880d681SAndroid Build Coastguard Worker if (!RelocMgr.hasValidRelocation(LocationOffset, LocationEndOffset, MyInfo) ||
2108*9880d681SAndroid Build Coastguard Worker (Flags & TF_InFunctionScope))
2109*9880d681SAndroid Build Coastguard Worker return Flags;
2110*9880d681SAndroid Build Coastguard Worker
2111*9880d681SAndroid Build Coastguard Worker if (Options.Verbose)
2112*9880d681SAndroid Build Coastguard Worker DIE.dump(outs(), const_cast<DWARFUnit *>(&OrigUnit), 0, 8 /* Indent */);
2113*9880d681SAndroid Build Coastguard Worker
2114*9880d681SAndroid Build Coastguard Worker return Flags | TF_Keep;
2115*9880d681SAndroid Build Coastguard Worker }
2116*9880d681SAndroid Build Coastguard Worker
2117*9880d681SAndroid Build Coastguard Worker /// \brief Check if a function describing DIE should be kept.
2118*9880d681SAndroid Build Coastguard Worker /// \returns updated TraversalFlags.
shouldKeepSubprogramDIE(RelocationManager & RelocMgr,const DWARFDebugInfoEntryMinimal & DIE,CompileUnit & Unit,CompileUnit::DIEInfo & MyInfo,unsigned Flags)2119*9880d681SAndroid Build Coastguard Worker unsigned DwarfLinker::shouldKeepSubprogramDIE(
2120*9880d681SAndroid Build Coastguard Worker RelocationManager &RelocMgr,
2121*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &DIE, CompileUnit &Unit,
2122*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &MyInfo, unsigned Flags) {
2123*9880d681SAndroid Build Coastguard Worker const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
2124*9880d681SAndroid Build Coastguard Worker
2125*9880d681SAndroid Build Coastguard Worker Flags |= TF_InFunctionScope;
2126*9880d681SAndroid Build Coastguard Worker
2127*9880d681SAndroid Build Coastguard Worker uint32_t LowPcIdx = Abbrev->findAttributeIndex(dwarf::DW_AT_low_pc);
2128*9880d681SAndroid Build Coastguard Worker if (LowPcIdx == -1U)
2129*9880d681SAndroid Build Coastguard Worker return Flags;
2130*9880d681SAndroid Build Coastguard Worker
2131*9880d681SAndroid Build Coastguard Worker uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
2132*9880d681SAndroid Build Coastguard Worker const DWARFUnit &OrigUnit = Unit.getOrigUnit();
2133*9880d681SAndroid Build Coastguard Worker uint32_t LowPcOffset, LowPcEndOffset;
2134*9880d681SAndroid Build Coastguard Worker std::tie(LowPcOffset, LowPcEndOffset) =
2135*9880d681SAndroid Build Coastguard Worker getAttributeOffsets(Abbrev, LowPcIdx, Offset, OrigUnit);
2136*9880d681SAndroid Build Coastguard Worker
2137*9880d681SAndroid Build Coastguard Worker uint64_t LowPc =
2138*9880d681SAndroid Build Coastguard Worker DIE.getAttributeValueAsAddress(&OrigUnit, dwarf::DW_AT_low_pc, -1ULL);
2139*9880d681SAndroid Build Coastguard Worker assert(LowPc != -1ULL && "low_pc attribute is not an address.");
2140*9880d681SAndroid Build Coastguard Worker if (LowPc == -1ULL ||
2141*9880d681SAndroid Build Coastguard Worker !RelocMgr.hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo))
2142*9880d681SAndroid Build Coastguard Worker return Flags;
2143*9880d681SAndroid Build Coastguard Worker
2144*9880d681SAndroid Build Coastguard Worker if (Options.Verbose)
2145*9880d681SAndroid Build Coastguard Worker DIE.dump(outs(), const_cast<DWARFUnit *>(&OrigUnit), 0, 8 /* Indent */);
2146*9880d681SAndroid Build Coastguard Worker
2147*9880d681SAndroid Build Coastguard Worker Flags |= TF_Keep;
2148*9880d681SAndroid Build Coastguard Worker
2149*9880d681SAndroid Build Coastguard Worker DWARFFormValue HighPcValue;
2150*9880d681SAndroid Build Coastguard Worker if (!DIE.getAttributeValue(&OrigUnit, dwarf::DW_AT_high_pc, HighPcValue)) {
2151*9880d681SAndroid Build Coastguard Worker reportWarning("Function without high_pc. Range will be discarded.\n",
2152*9880d681SAndroid Build Coastguard Worker &OrigUnit, &DIE);
2153*9880d681SAndroid Build Coastguard Worker return Flags;
2154*9880d681SAndroid Build Coastguard Worker }
2155*9880d681SAndroid Build Coastguard Worker
2156*9880d681SAndroid Build Coastguard Worker uint64_t HighPc;
2157*9880d681SAndroid Build Coastguard Worker if (HighPcValue.isFormClass(DWARFFormValue::FC_Address)) {
2158*9880d681SAndroid Build Coastguard Worker HighPc = *HighPcValue.getAsAddress(&OrigUnit);
2159*9880d681SAndroid Build Coastguard Worker } else {
2160*9880d681SAndroid Build Coastguard Worker assert(HighPcValue.isFormClass(DWARFFormValue::FC_Constant));
2161*9880d681SAndroid Build Coastguard Worker HighPc = LowPc + *HighPcValue.getAsUnsignedConstant();
2162*9880d681SAndroid Build Coastguard Worker }
2163*9880d681SAndroid Build Coastguard Worker
2164*9880d681SAndroid Build Coastguard Worker // Replace the debug map range with a more accurate one.
2165*9880d681SAndroid Build Coastguard Worker Ranges[LowPc] = std::make_pair(HighPc, MyInfo.AddrAdjust);
2166*9880d681SAndroid Build Coastguard Worker Unit.addFunctionRange(LowPc, HighPc, MyInfo.AddrAdjust);
2167*9880d681SAndroid Build Coastguard Worker return Flags;
2168*9880d681SAndroid Build Coastguard Worker }
2169*9880d681SAndroid Build Coastguard Worker
2170*9880d681SAndroid Build Coastguard Worker /// \brief Check if a DIE should be kept.
2171*9880d681SAndroid Build Coastguard Worker /// \returns updated TraversalFlags.
shouldKeepDIE(RelocationManager & RelocMgr,const DWARFDebugInfoEntryMinimal & DIE,CompileUnit & Unit,CompileUnit::DIEInfo & MyInfo,unsigned Flags)2172*9880d681SAndroid Build Coastguard Worker unsigned DwarfLinker::shouldKeepDIE(RelocationManager &RelocMgr,
2173*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &DIE,
2174*9880d681SAndroid Build Coastguard Worker CompileUnit &Unit,
2175*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &MyInfo,
2176*9880d681SAndroid Build Coastguard Worker unsigned Flags) {
2177*9880d681SAndroid Build Coastguard Worker switch (DIE.getTag()) {
2178*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_constant:
2179*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_variable:
2180*9880d681SAndroid Build Coastguard Worker return shouldKeepVariableDIE(RelocMgr, DIE, Unit, MyInfo, Flags);
2181*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_subprogram:
2182*9880d681SAndroid Build Coastguard Worker return shouldKeepSubprogramDIE(RelocMgr, DIE, Unit, MyInfo, Flags);
2183*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_module:
2184*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_imported_module:
2185*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_imported_declaration:
2186*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_imported_unit:
2187*9880d681SAndroid Build Coastguard Worker // We always want to keep these.
2188*9880d681SAndroid Build Coastguard Worker return Flags | TF_Keep;
2189*9880d681SAndroid Build Coastguard Worker }
2190*9880d681SAndroid Build Coastguard Worker
2191*9880d681SAndroid Build Coastguard Worker return Flags;
2192*9880d681SAndroid Build Coastguard Worker }
2193*9880d681SAndroid Build Coastguard Worker
2194*9880d681SAndroid Build Coastguard Worker /// \brief Mark the passed DIE as well as all the ones it depends on
2195*9880d681SAndroid Build Coastguard Worker /// as kept.
2196*9880d681SAndroid Build Coastguard Worker ///
2197*9880d681SAndroid Build Coastguard Worker /// This function is called by lookForDIEsToKeep on DIEs that are
2198*9880d681SAndroid Build Coastguard Worker /// newly discovered to be needed in the link. It recursively calls
2199*9880d681SAndroid Build Coastguard Worker /// back to lookForDIEsToKeep while adding TF_DependencyWalk to the
2200*9880d681SAndroid Build Coastguard Worker /// TraversalFlags to inform it that it's not doing the primary DIE
2201*9880d681SAndroid Build Coastguard Worker /// tree walk.
keepDIEAndDependencies(RelocationManager & RelocMgr,const DWARFDebugInfoEntryMinimal & Die,CompileUnit::DIEInfo & MyInfo,const DebugMapObject & DMO,CompileUnit & CU,bool UseODR)2202*9880d681SAndroid Build Coastguard Worker void DwarfLinker::keepDIEAndDependencies(RelocationManager &RelocMgr,
2203*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &Die,
2204*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &MyInfo,
2205*9880d681SAndroid Build Coastguard Worker const DebugMapObject &DMO,
2206*9880d681SAndroid Build Coastguard Worker CompileUnit &CU, bool UseODR) {
2207*9880d681SAndroid Build Coastguard Worker const DWARFUnit &Unit = CU.getOrigUnit();
2208*9880d681SAndroid Build Coastguard Worker MyInfo.Keep = true;
2209*9880d681SAndroid Build Coastguard Worker
2210*9880d681SAndroid Build Coastguard Worker // First mark all the parent chain as kept.
2211*9880d681SAndroid Build Coastguard Worker unsigned AncestorIdx = MyInfo.ParentIdx;
2212*9880d681SAndroid Build Coastguard Worker while (!CU.getInfo(AncestorIdx).Keep) {
2213*9880d681SAndroid Build Coastguard Worker unsigned ODRFlag = UseODR ? TF_ODR : 0;
2214*9880d681SAndroid Build Coastguard Worker lookForDIEsToKeep(RelocMgr, *Unit.getDIEAtIndex(AncestorIdx), DMO, CU,
2215*9880d681SAndroid Build Coastguard Worker TF_ParentWalk | TF_Keep | TF_DependencyWalk | ODRFlag);
2216*9880d681SAndroid Build Coastguard Worker AncestorIdx = CU.getInfo(AncestorIdx).ParentIdx;
2217*9880d681SAndroid Build Coastguard Worker }
2218*9880d681SAndroid Build Coastguard Worker
2219*9880d681SAndroid Build Coastguard Worker // Then we need to mark all the DIEs referenced by this DIE's
2220*9880d681SAndroid Build Coastguard Worker // attributes as kept.
2221*9880d681SAndroid Build Coastguard Worker DataExtractor Data = Unit.getDebugInfoExtractor();
2222*9880d681SAndroid Build Coastguard Worker const auto *Abbrev = Die.getAbbreviationDeclarationPtr();
2223*9880d681SAndroid Build Coastguard Worker uint32_t Offset = Die.getOffset() + getULEB128Size(Abbrev->getCode());
2224*9880d681SAndroid Build Coastguard Worker
2225*9880d681SAndroid Build Coastguard Worker // Mark all DIEs referenced through atttributes as kept.
2226*9880d681SAndroid Build Coastguard Worker for (const auto &AttrSpec : Abbrev->attributes()) {
2227*9880d681SAndroid Build Coastguard Worker DWARFFormValue Val(AttrSpec.Form);
2228*9880d681SAndroid Build Coastguard Worker
2229*9880d681SAndroid Build Coastguard Worker if (!Val.isFormClass(DWARFFormValue::FC_Reference)) {
2230*9880d681SAndroid Build Coastguard Worker DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset, &Unit);
2231*9880d681SAndroid Build Coastguard Worker continue;
2232*9880d681SAndroid Build Coastguard Worker }
2233*9880d681SAndroid Build Coastguard Worker
2234*9880d681SAndroid Build Coastguard Worker Val.extractValue(Data, &Offset, &Unit);
2235*9880d681SAndroid Build Coastguard Worker CompileUnit *ReferencedCU;
2236*9880d681SAndroid Build Coastguard Worker if (const auto *RefDIE =
2237*9880d681SAndroid Build Coastguard Worker resolveDIEReference(*this, MutableArrayRef<CompileUnit>(Units), Val,
2238*9880d681SAndroid Build Coastguard Worker Unit, Die, ReferencedCU)) {
2239*9880d681SAndroid Build Coastguard Worker uint32_t RefIdx = ReferencedCU->getOrigUnit().getDIEIndex(RefDIE);
2240*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &Info = ReferencedCU->getInfo(RefIdx);
2241*9880d681SAndroid Build Coastguard Worker // If the referenced DIE has a DeclContext that has already been
2242*9880d681SAndroid Build Coastguard Worker // emitted, then do not keep the one in this CU. We'll link to
2243*9880d681SAndroid Build Coastguard Worker // the canonical DIE in cloneDieReferenceAttribute.
2244*9880d681SAndroid Build Coastguard Worker // FIXME: compatibility with dsymutil-classic. UseODR shouldn't
2245*9880d681SAndroid Build Coastguard Worker // be necessary and could be advantageously replaced by
2246*9880d681SAndroid Build Coastguard Worker // ReferencedCU->hasODR() && CU.hasODR().
2247*9880d681SAndroid Build Coastguard Worker // FIXME: compatibility with dsymutil-classic. There is no
2248*9880d681SAndroid Build Coastguard Worker // reason not to unique ref_addr references.
2249*9880d681SAndroid Build Coastguard Worker if (AttrSpec.Form != dwarf::DW_FORM_ref_addr && UseODR && Info.Ctxt &&
2250*9880d681SAndroid Build Coastguard Worker Info.Ctxt != ReferencedCU->getInfo(Info.ParentIdx).Ctxt &&
2251*9880d681SAndroid Build Coastguard Worker Info.Ctxt->getCanonicalDIEOffset() && isODRAttribute(AttrSpec.Attr))
2252*9880d681SAndroid Build Coastguard Worker continue;
2253*9880d681SAndroid Build Coastguard Worker
2254*9880d681SAndroid Build Coastguard Worker // Keep a module forward declaration if there is no definition.
2255*9880d681SAndroid Build Coastguard Worker if (!(isODRAttribute(AttrSpec.Attr) && Info.Ctxt &&
2256*9880d681SAndroid Build Coastguard Worker Info.Ctxt->getCanonicalDIEOffset()))
2257*9880d681SAndroid Build Coastguard Worker Info.Prune = false;
2258*9880d681SAndroid Build Coastguard Worker
2259*9880d681SAndroid Build Coastguard Worker unsigned ODRFlag = UseODR ? TF_ODR : 0;
2260*9880d681SAndroid Build Coastguard Worker lookForDIEsToKeep(RelocMgr, *RefDIE, DMO, *ReferencedCU,
2261*9880d681SAndroid Build Coastguard Worker TF_Keep | TF_DependencyWalk | ODRFlag);
2262*9880d681SAndroid Build Coastguard Worker }
2263*9880d681SAndroid Build Coastguard Worker }
2264*9880d681SAndroid Build Coastguard Worker }
2265*9880d681SAndroid Build Coastguard Worker
2266*9880d681SAndroid Build Coastguard Worker /// \brief Recursively walk the \p DIE tree and look for DIEs to
2267*9880d681SAndroid Build Coastguard Worker /// keep. Store that information in \p CU's DIEInfo.
2268*9880d681SAndroid Build Coastguard Worker ///
2269*9880d681SAndroid Build Coastguard Worker /// This function is the entry point of the DIE selection
2270*9880d681SAndroid Build Coastguard Worker /// algorithm. It is expected to walk the DIE tree in file order and
2271*9880d681SAndroid Build Coastguard Worker /// (though the mediation of its helper) call hasValidRelocation() on
2272*9880d681SAndroid Build Coastguard Worker /// each DIE that might be a 'root DIE' (See DwarfLinker class
2273*9880d681SAndroid Build Coastguard Worker /// comment).
2274*9880d681SAndroid Build Coastguard Worker /// While walking the dependencies of root DIEs, this function is
2275*9880d681SAndroid Build Coastguard Worker /// also called, but during these dependency walks the file order is
2276*9880d681SAndroid Build Coastguard Worker /// not respected. The TF_DependencyWalk flag tells us which kind of
2277*9880d681SAndroid Build Coastguard Worker /// traversal we are currently doing.
lookForDIEsToKeep(RelocationManager & RelocMgr,const DWARFDebugInfoEntryMinimal & Die,const DebugMapObject & DMO,CompileUnit & CU,unsigned Flags)2278*9880d681SAndroid Build Coastguard Worker void DwarfLinker::lookForDIEsToKeep(RelocationManager &RelocMgr,
2279*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &Die,
2280*9880d681SAndroid Build Coastguard Worker const DebugMapObject &DMO, CompileUnit &CU,
2281*9880d681SAndroid Build Coastguard Worker unsigned Flags) {
2282*9880d681SAndroid Build Coastguard Worker unsigned Idx = CU.getOrigUnit().getDIEIndex(&Die);
2283*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &MyInfo = CU.getInfo(Idx);
2284*9880d681SAndroid Build Coastguard Worker bool AlreadyKept = MyInfo.Keep;
2285*9880d681SAndroid Build Coastguard Worker if (MyInfo.Prune)
2286*9880d681SAndroid Build Coastguard Worker return;
2287*9880d681SAndroid Build Coastguard Worker
2288*9880d681SAndroid Build Coastguard Worker // If the Keep flag is set, we are marking a required DIE's
2289*9880d681SAndroid Build Coastguard Worker // dependencies. If our target is already marked as kept, we're all
2290*9880d681SAndroid Build Coastguard Worker // set.
2291*9880d681SAndroid Build Coastguard Worker if ((Flags & TF_DependencyWalk) && AlreadyKept)
2292*9880d681SAndroid Build Coastguard Worker return;
2293*9880d681SAndroid Build Coastguard Worker
2294*9880d681SAndroid Build Coastguard Worker // We must not call shouldKeepDIE while called from keepDIEAndDependencies,
2295*9880d681SAndroid Build Coastguard Worker // because it would screw up the relocation finding logic.
2296*9880d681SAndroid Build Coastguard Worker if (!(Flags & TF_DependencyWalk))
2297*9880d681SAndroid Build Coastguard Worker Flags = shouldKeepDIE(RelocMgr, Die, CU, MyInfo, Flags);
2298*9880d681SAndroid Build Coastguard Worker
2299*9880d681SAndroid Build Coastguard Worker // If it is a newly kept DIE mark it as well as all its dependencies as kept.
2300*9880d681SAndroid Build Coastguard Worker if (!AlreadyKept && (Flags & TF_Keep)) {
2301*9880d681SAndroid Build Coastguard Worker bool UseOdr = (Flags & TF_DependencyWalk) ? (Flags & TF_ODR) : CU.hasODR();
2302*9880d681SAndroid Build Coastguard Worker keepDIEAndDependencies(RelocMgr, Die, MyInfo, DMO, CU, UseOdr);
2303*9880d681SAndroid Build Coastguard Worker }
2304*9880d681SAndroid Build Coastguard Worker // The TF_ParentWalk flag tells us that we are currently walking up
2305*9880d681SAndroid Build Coastguard Worker // the parent chain of a required DIE, and we don't want to mark all
2306*9880d681SAndroid Build Coastguard Worker // the children of the parents as kept (consider for example a
2307*9880d681SAndroid Build Coastguard Worker // DW_TAG_namespace node in the parent chain). There are however a
2308*9880d681SAndroid Build Coastguard Worker // set of DIE types for which we want to ignore that directive and still
2309*9880d681SAndroid Build Coastguard Worker // walk their children.
2310*9880d681SAndroid Build Coastguard Worker if (dieNeedsChildrenToBeMeaningful(Die.getTag()))
2311*9880d681SAndroid Build Coastguard Worker Flags &= ~TF_ParentWalk;
2312*9880d681SAndroid Build Coastguard Worker
2313*9880d681SAndroid Build Coastguard Worker if (!Die.hasChildren() || (Flags & TF_ParentWalk))
2314*9880d681SAndroid Build Coastguard Worker return;
2315*9880d681SAndroid Build Coastguard Worker
2316*9880d681SAndroid Build Coastguard Worker for (auto *Child = Die.getFirstChild(); Child && !Child->isNULL();
2317*9880d681SAndroid Build Coastguard Worker Child = Child->getSibling())
2318*9880d681SAndroid Build Coastguard Worker lookForDIEsToKeep(RelocMgr, *Child, DMO, CU, Flags);
2319*9880d681SAndroid Build Coastguard Worker }
2320*9880d681SAndroid Build Coastguard Worker
2321*9880d681SAndroid Build Coastguard Worker /// \brief Assign an abbreviation numer to \p Abbrev.
2322*9880d681SAndroid Build Coastguard Worker ///
2323*9880d681SAndroid Build Coastguard Worker /// Our DIEs get freed after every DebugMapObject has been processed,
2324*9880d681SAndroid Build Coastguard Worker /// thus the FoldingSet we use to unique DIEAbbrevs cannot refer to
2325*9880d681SAndroid Build Coastguard Worker /// the instances hold by the DIEs. When we encounter an abbreviation
2326*9880d681SAndroid Build Coastguard Worker /// that we don't know, we create a permanent copy of it.
AssignAbbrev(DIEAbbrev & Abbrev)2327*9880d681SAndroid Build Coastguard Worker void DwarfLinker::AssignAbbrev(DIEAbbrev &Abbrev) {
2328*9880d681SAndroid Build Coastguard Worker // Check the set for priors.
2329*9880d681SAndroid Build Coastguard Worker FoldingSetNodeID ID;
2330*9880d681SAndroid Build Coastguard Worker Abbrev.Profile(ID);
2331*9880d681SAndroid Build Coastguard Worker void *InsertToken;
2332*9880d681SAndroid Build Coastguard Worker DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken);
2333*9880d681SAndroid Build Coastguard Worker
2334*9880d681SAndroid Build Coastguard Worker // If it's newly added.
2335*9880d681SAndroid Build Coastguard Worker if (InSet) {
2336*9880d681SAndroid Build Coastguard Worker // Assign existing abbreviation number.
2337*9880d681SAndroid Build Coastguard Worker Abbrev.setNumber(InSet->getNumber());
2338*9880d681SAndroid Build Coastguard Worker } else {
2339*9880d681SAndroid Build Coastguard Worker // Add to abbreviation list.
2340*9880d681SAndroid Build Coastguard Worker Abbreviations.push_back(
2341*9880d681SAndroid Build Coastguard Worker llvm::make_unique<DIEAbbrev>(Abbrev.getTag(), Abbrev.hasChildren()));
2342*9880d681SAndroid Build Coastguard Worker for (const auto &Attr : Abbrev.getData())
2343*9880d681SAndroid Build Coastguard Worker Abbreviations.back()->AddAttribute(Attr.getAttribute(), Attr.getForm());
2344*9880d681SAndroid Build Coastguard Worker AbbreviationsSet.InsertNode(Abbreviations.back().get(), InsertToken);
2345*9880d681SAndroid Build Coastguard Worker // Assign the unique abbreviation number.
2346*9880d681SAndroid Build Coastguard Worker Abbrev.setNumber(Abbreviations.size());
2347*9880d681SAndroid Build Coastguard Worker Abbreviations.back()->setNumber(Abbreviations.size());
2348*9880d681SAndroid Build Coastguard Worker }
2349*9880d681SAndroid Build Coastguard Worker }
2350*9880d681SAndroid Build Coastguard Worker
cloneStringAttribute(DIE & Die,AttributeSpec AttrSpec,const DWARFFormValue & Val,const DWARFUnit & U)2351*9880d681SAndroid Build Coastguard Worker unsigned DwarfLinker::DIECloner::cloneStringAttribute(DIE &Die,
2352*9880d681SAndroid Build Coastguard Worker AttributeSpec AttrSpec,
2353*9880d681SAndroid Build Coastguard Worker const DWARFFormValue &Val,
2354*9880d681SAndroid Build Coastguard Worker const DWARFUnit &U) {
2355*9880d681SAndroid Build Coastguard Worker // Switch everything to out of line strings.
2356*9880d681SAndroid Build Coastguard Worker const char *String = *Val.getAsCString(&U);
2357*9880d681SAndroid Build Coastguard Worker unsigned Offset = Linker.StringPool.getStringOffset(String);
2358*9880d681SAndroid Build Coastguard Worker Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_strp,
2359*9880d681SAndroid Build Coastguard Worker DIEInteger(Offset));
2360*9880d681SAndroid Build Coastguard Worker return 4;
2361*9880d681SAndroid Build Coastguard Worker }
2362*9880d681SAndroid Build Coastguard Worker
cloneDieReferenceAttribute(DIE & Die,const DWARFDebugInfoEntryMinimal & InputDIE,AttributeSpec AttrSpec,unsigned AttrSize,const DWARFFormValue & Val,CompileUnit & Unit)2363*9880d681SAndroid Build Coastguard Worker unsigned DwarfLinker::DIECloner::cloneDieReferenceAttribute(
2364*9880d681SAndroid Build Coastguard Worker DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE,
2365*9880d681SAndroid Build Coastguard Worker AttributeSpec AttrSpec, unsigned AttrSize, const DWARFFormValue &Val,
2366*9880d681SAndroid Build Coastguard Worker CompileUnit &Unit) {
2367*9880d681SAndroid Build Coastguard Worker const DWARFUnit &U = Unit.getOrigUnit();
2368*9880d681SAndroid Build Coastguard Worker uint32_t Ref = *Val.getAsReference(&U);
2369*9880d681SAndroid Build Coastguard Worker DIE *NewRefDie = nullptr;
2370*9880d681SAndroid Build Coastguard Worker CompileUnit *RefUnit = nullptr;
2371*9880d681SAndroid Build Coastguard Worker DeclContext *Ctxt = nullptr;
2372*9880d681SAndroid Build Coastguard Worker
2373*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal *RefDie =
2374*9880d681SAndroid Build Coastguard Worker resolveDIEReference(Linker, CompileUnits, Val, U, InputDIE, RefUnit);
2375*9880d681SAndroid Build Coastguard Worker
2376*9880d681SAndroid Build Coastguard Worker // If the referenced DIE is not found, drop the attribute.
2377*9880d681SAndroid Build Coastguard Worker if (!RefDie)
2378*9880d681SAndroid Build Coastguard Worker return 0;
2379*9880d681SAndroid Build Coastguard Worker
2380*9880d681SAndroid Build Coastguard Worker unsigned Idx = RefUnit->getOrigUnit().getDIEIndex(RefDie);
2381*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &RefInfo = RefUnit->getInfo(Idx);
2382*9880d681SAndroid Build Coastguard Worker
2383*9880d681SAndroid Build Coastguard Worker // If we already have emitted an equivalent DeclContext, just point
2384*9880d681SAndroid Build Coastguard Worker // at it.
2385*9880d681SAndroid Build Coastguard Worker if (isODRAttribute(AttrSpec.Attr)) {
2386*9880d681SAndroid Build Coastguard Worker Ctxt = RefInfo.Ctxt;
2387*9880d681SAndroid Build Coastguard Worker if (Ctxt && Ctxt->getCanonicalDIEOffset()) {
2388*9880d681SAndroid Build Coastguard Worker DIEInteger Attr(Ctxt->getCanonicalDIEOffset());
2389*9880d681SAndroid Build Coastguard Worker Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
2390*9880d681SAndroid Build Coastguard Worker dwarf::DW_FORM_ref_addr, Attr);
2391*9880d681SAndroid Build Coastguard Worker return getRefAddrSize(U);
2392*9880d681SAndroid Build Coastguard Worker }
2393*9880d681SAndroid Build Coastguard Worker }
2394*9880d681SAndroid Build Coastguard Worker
2395*9880d681SAndroid Build Coastguard Worker if (!RefInfo.Clone) {
2396*9880d681SAndroid Build Coastguard Worker assert(Ref > InputDIE.getOffset());
2397*9880d681SAndroid Build Coastguard Worker // We haven't cloned this DIE yet. Just create an empty one and
2398*9880d681SAndroid Build Coastguard Worker // store it. It'll get really cloned when we process it.
2399*9880d681SAndroid Build Coastguard Worker RefInfo.Clone = DIE::get(DIEAlloc, dwarf::Tag(RefDie->getTag()));
2400*9880d681SAndroid Build Coastguard Worker }
2401*9880d681SAndroid Build Coastguard Worker NewRefDie = RefInfo.Clone;
2402*9880d681SAndroid Build Coastguard Worker
2403*9880d681SAndroid Build Coastguard Worker if (AttrSpec.Form == dwarf::DW_FORM_ref_addr ||
2404*9880d681SAndroid Build Coastguard Worker (Unit.hasODR() && isODRAttribute(AttrSpec.Attr))) {
2405*9880d681SAndroid Build Coastguard Worker // We cannot currently rely on a DIEEntry to emit ref_addr
2406*9880d681SAndroid Build Coastguard Worker // references, because the implementation calls back to DwarfDebug
2407*9880d681SAndroid Build Coastguard Worker // to find the unit offset. (We don't have a DwarfDebug)
2408*9880d681SAndroid Build Coastguard Worker // FIXME: we should be able to design DIEEntry reliance on
2409*9880d681SAndroid Build Coastguard Worker // DwarfDebug away.
2410*9880d681SAndroid Build Coastguard Worker uint64_t Attr;
2411*9880d681SAndroid Build Coastguard Worker if (Ref < InputDIE.getOffset()) {
2412*9880d681SAndroid Build Coastguard Worker // We must have already cloned that DIE.
2413*9880d681SAndroid Build Coastguard Worker uint32_t NewRefOffset =
2414*9880d681SAndroid Build Coastguard Worker RefUnit->getStartOffset() + NewRefDie->getOffset();
2415*9880d681SAndroid Build Coastguard Worker Attr = NewRefOffset;
2416*9880d681SAndroid Build Coastguard Worker Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
2417*9880d681SAndroid Build Coastguard Worker dwarf::DW_FORM_ref_addr, DIEInteger(Attr));
2418*9880d681SAndroid Build Coastguard Worker } else {
2419*9880d681SAndroid Build Coastguard Worker // A forward reference. Note and fixup later.
2420*9880d681SAndroid Build Coastguard Worker Attr = 0xBADDEF;
2421*9880d681SAndroid Build Coastguard Worker Unit.noteForwardReference(
2422*9880d681SAndroid Build Coastguard Worker NewRefDie, RefUnit, Ctxt,
2423*9880d681SAndroid Build Coastguard Worker Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
2424*9880d681SAndroid Build Coastguard Worker dwarf::DW_FORM_ref_addr, DIEInteger(Attr)));
2425*9880d681SAndroid Build Coastguard Worker }
2426*9880d681SAndroid Build Coastguard Worker return getRefAddrSize(U);
2427*9880d681SAndroid Build Coastguard Worker }
2428*9880d681SAndroid Build Coastguard Worker
2429*9880d681SAndroid Build Coastguard Worker Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
2430*9880d681SAndroid Build Coastguard Worker dwarf::Form(AttrSpec.Form), DIEEntry(*NewRefDie));
2431*9880d681SAndroid Build Coastguard Worker return AttrSize;
2432*9880d681SAndroid Build Coastguard Worker }
2433*9880d681SAndroid Build Coastguard Worker
cloneBlockAttribute(DIE & Die,AttributeSpec AttrSpec,const DWARFFormValue & Val,unsigned AttrSize)2434*9880d681SAndroid Build Coastguard Worker unsigned DwarfLinker::DIECloner::cloneBlockAttribute(DIE &Die,
2435*9880d681SAndroid Build Coastguard Worker AttributeSpec AttrSpec,
2436*9880d681SAndroid Build Coastguard Worker const DWARFFormValue &Val,
2437*9880d681SAndroid Build Coastguard Worker unsigned AttrSize) {
2438*9880d681SAndroid Build Coastguard Worker DIEValueList *Attr;
2439*9880d681SAndroid Build Coastguard Worker DIEValue Value;
2440*9880d681SAndroid Build Coastguard Worker DIELoc *Loc = nullptr;
2441*9880d681SAndroid Build Coastguard Worker DIEBlock *Block = nullptr;
2442*9880d681SAndroid Build Coastguard Worker // Just copy the block data over.
2443*9880d681SAndroid Build Coastguard Worker if (AttrSpec.Form == dwarf::DW_FORM_exprloc) {
2444*9880d681SAndroid Build Coastguard Worker Loc = new (DIEAlloc) DIELoc;
2445*9880d681SAndroid Build Coastguard Worker Linker.DIELocs.push_back(Loc);
2446*9880d681SAndroid Build Coastguard Worker } else {
2447*9880d681SAndroid Build Coastguard Worker Block = new (DIEAlloc) DIEBlock;
2448*9880d681SAndroid Build Coastguard Worker Linker.DIEBlocks.push_back(Block);
2449*9880d681SAndroid Build Coastguard Worker }
2450*9880d681SAndroid Build Coastguard Worker Attr = Loc ? static_cast<DIEValueList *>(Loc)
2451*9880d681SAndroid Build Coastguard Worker : static_cast<DIEValueList *>(Block);
2452*9880d681SAndroid Build Coastguard Worker
2453*9880d681SAndroid Build Coastguard Worker if (Loc)
2454*9880d681SAndroid Build Coastguard Worker Value = DIEValue(dwarf::Attribute(AttrSpec.Attr),
2455*9880d681SAndroid Build Coastguard Worker dwarf::Form(AttrSpec.Form), Loc);
2456*9880d681SAndroid Build Coastguard Worker else
2457*9880d681SAndroid Build Coastguard Worker Value = DIEValue(dwarf::Attribute(AttrSpec.Attr),
2458*9880d681SAndroid Build Coastguard Worker dwarf::Form(AttrSpec.Form), Block);
2459*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Bytes = *Val.getAsBlock();
2460*9880d681SAndroid Build Coastguard Worker for (auto Byte : Bytes)
2461*9880d681SAndroid Build Coastguard Worker Attr->addValue(DIEAlloc, static_cast<dwarf::Attribute>(0),
2462*9880d681SAndroid Build Coastguard Worker dwarf::DW_FORM_data1, DIEInteger(Byte));
2463*9880d681SAndroid Build Coastguard Worker // FIXME: If DIEBlock and DIELoc just reuses the Size field of
2464*9880d681SAndroid Build Coastguard Worker // the DIE class, this if could be replaced by
2465*9880d681SAndroid Build Coastguard Worker // Attr->setSize(Bytes.size()).
2466*9880d681SAndroid Build Coastguard Worker if (Linker.Streamer) {
2467*9880d681SAndroid Build Coastguard Worker auto *AsmPrinter = &Linker.Streamer->getAsmPrinter();
2468*9880d681SAndroid Build Coastguard Worker if (Loc)
2469*9880d681SAndroid Build Coastguard Worker Loc->ComputeSize(AsmPrinter);
2470*9880d681SAndroid Build Coastguard Worker else
2471*9880d681SAndroid Build Coastguard Worker Block->ComputeSize(AsmPrinter);
2472*9880d681SAndroid Build Coastguard Worker }
2473*9880d681SAndroid Build Coastguard Worker Die.addValue(DIEAlloc, Value);
2474*9880d681SAndroid Build Coastguard Worker return AttrSize;
2475*9880d681SAndroid Build Coastguard Worker }
2476*9880d681SAndroid Build Coastguard Worker
cloneAddressAttribute(DIE & Die,AttributeSpec AttrSpec,const DWARFFormValue & Val,const CompileUnit & Unit,AttributesInfo & Info)2477*9880d681SAndroid Build Coastguard Worker unsigned DwarfLinker::DIECloner::cloneAddressAttribute(
2478*9880d681SAndroid Build Coastguard Worker DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
2479*9880d681SAndroid Build Coastguard Worker const CompileUnit &Unit, AttributesInfo &Info) {
2480*9880d681SAndroid Build Coastguard Worker uint64_t Addr = *Val.getAsAddress(&Unit.getOrigUnit());
2481*9880d681SAndroid Build Coastguard Worker if (AttrSpec.Attr == dwarf::DW_AT_low_pc) {
2482*9880d681SAndroid Build Coastguard Worker if (Die.getTag() == dwarf::DW_TAG_inlined_subroutine ||
2483*9880d681SAndroid Build Coastguard Worker Die.getTag() == dwarf::DW_TAG_lexical_block)
2484*9880d681SAndroid Build Coastguard Worker // The low_pc of a block or inline subroutine might get
2485*9880d681SAndroid Build Coastguard Worker // relocated because it happens to match the low_pc of the
2486*9880d681SAndroid Build Coastguard Worker // enclosing subprogram. To prevent issues with that, always use
2487*9880d681SAndroid Build Coastguard Worker // the low_pc from the input DIE if relocations have been applied.
2488*9880d681SAndroid Build Coastguard Worker Addr = (Info.OrigLowPc != UINT64_MAX ? Info.OrigLowPc : Addr) +
2489*9880d681SAndroid Build Coastguard Worker Info.PCOffset;
2490*9880d681SAndroid Build Coastguard Worker else if (Die.getTag() == dwarf::DW_TAG_compile_unit) {
2491*9880d681SAndroid Build Coastguard Worker Addr = Unit.getLowPc();
2492*9880d681SAndroid Build Coastguard Worker if (Addr == UINT64_MAX)
2493*9880d681SAndroid Build Coastguard Worker return 0;
2494*9880d681SAndroid Build Coastguard Worker }
2495*9880d681SAndroid Build Coastguard Worker Info.HasLowPc = true;
2496*9880d681SAndroid Build Coastguard Worker } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc) {
2497*9880d681SAndroid Build Coastguard Worker if (Die.getTag() == dwarf::DW_TAG_compile_unit) {
2498*9880d681SAndroid Build Coastguard Worker if (uint64_t HighPc = Unit.getHighPc())
2499*9880d681SAndroid Build Coastguard Worker Addr = HighPc;
2500*9880d681SAndroid Build Coastguard Worker else
2501*9880d681SAndroid Build Coastguard Worker return 0;
2502*9880d681SAndroid Build Coastguard Worker } else
2503*9880d681SAndroid Build Coastguard Worker // If we have a high_pc recorded for the input DIE, use
2504*9880d681SAndroid Build Coastguard Worker // it. Otherwise (when no relocations where applied) just use the
2505*9880d681SAndroid Build Coastguard Worker // one we just decoded.
2506*9880d681SAndroid Build Coastguard Worker Addr = (Info.OrigHighPc ? Info.OrigHighPc : Addr) + Info.PCOffset;
2507*9880d681SAndroid Build Coastguard Worker }
2508*9880d681SAndroid Build Coastguard Worker
2509*9880d681SAndroid Build Coastguard Worker Die.addValue(DIEAlloc, static_cast<dwarf::Attribute>(AttrSpec.Attr),
2510*9880d681SAndroid Build Coastguard Worker static_cast<dwarf::Form>(AttrSpec.Form), DIEInteger(Addr));
2511*9880d681SAndroid Build Coastguard Worker return Unit.getOrigUnit().getAddressByteSize();
2512*9880d681SAndroid Build Coastguard Worker }
2513*9880d681SAndroid Build Coastguard Worker
cloneScalarAttribute(DIE & Die,const DWARFDebugInfoEntryMinimal & InputDIE,CompileUnit & Unit,AttributeSpec AttrSpec,const DWARFFormValue & Val,unsigned AttrSize,AttributesInfo & Info)2514*9880d681SAndroid Build Coastguard Worker unsigned DwarfLinker::DIECloner::cloneScalarAttribute(
2515*9880d681SAndroid Build Coastguard Worker DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE, CompileUnit &Unit,
2516*9880d681SAndroid Build Coastguard Worker AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize,
2517*9880d681SAndroid Build Coastguard Worker AttributesInfo &Info) {
2518*9880d681SAndroid Build Coastguard Worker uint64_t Value;
2519*9880d681SAndroid Build Coastguard Worker if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
2520*9880d681SAndroid Build Coastguard Worker Die.getTag() == dwarf::DW_TAG_compile_unit) {
2521*9880d681SAndroid Build Coastguard Worker if (Unit.getLowPc() == -1ULL)
2522*9880d681SAndroid Build Coastguard Worker return 0;
2523*9880d681SAndroid Build Coastguard Worker // Dwarf >= 4 high_pc is an size, not an address.
2524*9880d681SAndroid Build Coastguard Worker Value = Unit.getHighPc() - Unit.getLowPc();
2525*9880d681SAndroid Build Coastguard Worker } else if (AttrSpec.Form == dwarf::DW_FORM_sec_offset)
2526*9880d681SAndroid Build Coastguard Worker Value = *Val.getAsSectionOffset();
2527*9880d681SAndroid Build Coastguard Worker else if (AttrSpec.Form == dwarf::DW_FORM_sdata)
2528*9880d681SAndroid Build Coastguard Worker Value = *Val.getAsSignedConstant();
2529*9880d681SAndroid Build Coastguard Worker else if (auto OptionalValue = Val.getAsUnsignedConstant())
2530*9880d681SAndroid Build Coastguard Worker Value = *OptionalValue;
2531*9880d681SAndroid Build Coastguard Worker else {
2532*9880d681SAndroid Build Coastguard Worker Linker.reportWarning(
2533*9880d681SAndroid Build Coastguard Worker "Unsupported scalar attribute form. Dropping attribute.",
2534*9880d681SAndroid Build Coastguard Worker &Unit.getOrigUnit(), &InputDIE);
2535*9880d681SAndroid Build Coastguard Worker return 0;
2536*9880d681SAndroid Build Coastguard Worker }
2537*9880d681SAndroid Build Coastguard Worker PatchLocation Patch =
2538*9880d681SAndroid Build Coastguard Worker Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
2539*9880d681SAndroid Build Coastguard Worker dwarf::Form(AttrSpec.Form), DIEInteger(Value));
2540*9880d681SAndroid Build Coastguard Worker if (AttrSpec.Attr == dwarf::DW_AT_ranges)
2541*9880d681SAndroid Build Coastguard Worker Unit.noteRangeAttribute(Die, Patch);
2542*9880d681SAndroid Build Coastguard Worker
2543*9880d681SAndroid Build Coastguard Worker // A more generic way to check for location attributes would be
2544*9880d681SAndroid Build Coastguard Worker // nice, but it's very unlikely that any other attribute needs a
2545*9880d681SAndroid Build Coastguard Worker // location list.
2546*9880d681SAndroid Build Coastguard Worker else if (AttrSpec.Attr == dwarf::DW_AT_location ||
2547*9880d681SAndroid Build Coastguard Worker AttrSpec.Attr == dwarf::DW_AT_frame_base)
2548*9880d681SAndroid Build Coastguard Worker Unit.noteLocationAttribute(Patch, Info.PCOffset);
2549*9880d681SAndroid Build Coastguard Worker else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
2550*9880d681SAndroid Build Coastguard Worker Info.IsDeclaration = true;
2551*9880d681SAndroid Build Coastguard Worker
2552*9880d681SAndroid Build Coastguard Worker return AttrSize;
2553*9880d681SAndroid Build Coastguard Worker }
2554*9880d681SAndroid Build Coastguard Worker
2555*9880d681SAndroid Build Coastguard Worker /// \brief Clone \p InputDIE's attribute described by \p AttrSpec with
2556*9880d681SAndroid Build Coastguard Worker /// value \p Val, and add it to \p Die.
2557*9880d681SAndroid Build Coastguard Worker /// \returns the size of the cloned attribute.
cloneAttribute(DIE & Die,const DWARFDebugInfoEntryMinimal & InputDIE,CompileUnit & Unit,const DWARFFormValue & Val,const AttributeSpec AttrSpec,unsigned AttrSize,AttributesInfo & Info)2558*9880d681SAndroid Build Coastguard Worker unsigned DwarfLinker::DIECloner::cloneAttribute(
2559*9880d681SAndroid Build Coastguard Worker DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE, CompileUnit &Unit,
2560*9880d681SAndroid Build Coastguard Worker const DWARFFormValue &Val, const AttributeSpec AttrSpec, unsigned AttrSize,
2561*9880d681SAndroid Build Coastguard Worker AttributesInfo &Info) {
2562*9880d681SAndroid Build Coastguard Worker const DWARFUnit &U = Unit.getOrigUnit();
2563*9880d681SAndroid Build Coastguard Worker
2564*9880d681SAndroid Build Coastguard Worker switch (AttrSpec.Form) {
2565*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_strp:
2566*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_string:
2567*9880d681SAndroid Build Coastguard Worker return cloneStringAttribute(Die, AttrSpec, Val, U);
2568*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_ref_addr:
2569*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_ref1:
2570*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_ref2:
2571*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_ref4:
2572*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_ref8:
2573*9880d681SAndroid Build Coastguard Worker return cloneDieReferenceAttribute(Die, InputDIE, AttrSpec, AttrSize, Val,
2574*9880d681SAndroid Build Coastguard Worker Unit);
2575*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_block:
2576*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_block1:
2577*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_block2:
2578*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_block4:
2579*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_exprloc:
2580*9880d681SAndroid Build Coastguard Worker return cloneBlockAttribute(Die, AttrSpec, Val, AttrSize);
2581*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_addr:
2582*9880d681SAndroid Build Coastguard Worker return cloneAddressAttribute(Die, AttrSpec, Val, Unit, Info);
2583*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_data1:
2584*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_data2:
2585*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_data4:
2586*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_data8:
2587*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_udata:
2588*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_sdata:
2589*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_sec_offset:
2590*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_flag:
2591*9880d681SAndroid Build Coastguard Worker case dwarf::DW_FORM_flag_present:
2592*9880d681SAndroid Build Coastguard Worker return cloneScalarAttribute(Die, InputDIE, Unit, AttrSpec, Val, AttrSize,
2593*9880d681SAndroid Build Coastguard Worker Info);
2594*9880d681SAndroid Build Coastguard Worker default:
2595*9880d681SAndroid Build Coastguard Worker Linker.reportWarning(
2596*9880d681SAndroid Build Coastguard Worker "Unsupported attribute form in cloneAttribute. Dropping.", &U,
2597*9880d681SAndroid Build Coastguard Worker &InputDIE);
2598*9880d681SAndroid Build Coastguard Worker }
2599*9880d681SAndroid Build Coastguard Worker
2600*9880d681SAndroid Build Coastguard Worker return 0;
2601*9880d681SAndroid Build Coastguard Worker }
2602*9880d681SAndroid Build Coastguard Worker
2603*9880d681SAndroid Build Coastguard Worker /// \brief Apply the valid relocations found by findValidRelocs() to
2604*9880d681SAndroid Build Coastguard Worker /// the buffer \p Data, taking into account that Data is at \p BaseOffset
2605*9880d681SAndroid Build Coastguard Worker /// in the debug_info section.
2606*9880d681SAndroid Build Coastguard Worker ///
2607*9880d681SAndroid Build Coastguard Worker /// Like for findValidRelocs(), this function must be called with
2608*9880d681SAndroid Build Coastguard Worker /// monotonic \p BaseOffset values.
2609*9880d681SAndroid Build Coastguard Worker ///
2610*9880d681SAndroid Build Coastguard Worker /// \returns wether any reloc has been applied.
2611*9880d681SAndroid Build Coastguard Worker bool DwarfLinker::RelocationManager::
applyValidRelocs(MutableArrayRef<char> Data,uint32_t BaseOffset,bool isLittleEndian)2612*9880d681SAndroid Build Coastguard Worker applyValidRelocs(MutableArrayRef<char> Data, uint32_t BaseOffset,
2613*9880d681SAndroid Build Coastguard Worker bool isLittleEndian) {
2614*9880d681SAndroid Build Coastguard Worker assert((NextValidReloc == 0 ||
2615*9880d681SAndroid Build Coastguard Worker BaseOffset > ValidRelocs[NextValidReloc - 1].Offset) &&
2616*9880d681SAndroid Build Coastguard Worker "BaseOffset should only be increasing.");
2617*9880d681SAndroid Build Coastguard Worker if (NextValidReloc >= ValidRelocs.size())
2618*9880d681SAndroid Build Coastguard Worker return false;
2619*9880d681SAndroid Build Coastguard Worker
2620*9880d681SAndroid Build Coastguard Worker // Skip relocs that haven't been applied.
2621*9880d681SAndroid Build Coastguard Worker while (NextValidReloc < ValidRelocs.size() &&
2622*9880d681SAndroid Build Coastguard Worker ValidRelocs[NextValidReloc].Offset < BaseOffset)
2623*9880d681SAndroid Build Coastguard Worker ++NextValidReloc;
2624*9880d681SAndroid Build Coastguard Worker
2625*9880d681SAndroid Build Coastguard Worker bool Applied = false;
2626*9880d681SAndroid Build Coastguard Worker uint64_t EndOffset = BaseOffset + Data.size();
2627*9880d681SAndroid Build Coastguard Worker while (NextValidReloc < ValidRelocs.size() &&
2628*9880d681SAndroid Build Coastguard Worker ValidRelocs[NextValidReloc].Offset >= BaseOffset &&
2629*9880d681SAndroid Build Coastguard Worker ValidRelocs[NextValidReloc].Offset < EndOffset) {
2630*9880d681SAndroid Build Coastguard Worker const auto &ValidReloc = ValidRelocs[NextValidReloc++];
2631*9880d681SAndroid Build Coastguard Worker assert(ValidReloc.Offset - BaseOffset < Data.size());
2632*9880d681SAndroid Build Coastguard Worker assert(ValidReloc.Offset - BaseOffset + ValidReloc.Size <= Data.size());
2633*9880d681SAndroid Build Coastguard Worker char Buf[8];
2634*9880d681SAndroid Build Coastguard Worker uint64_t Value = ValidReloc.Mapping->getValue().BinaryAddress;
2635*9880d681SAndroid Build Coastguard Worker Value += ValidReloc.Addend;
2636*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i != ValidReloc.Size; ++i) {
2637*9880d681SAndroid Build Coastguard Worker unsigned Index = isLittleEndian ? i : (ValidReloc.Size - i - 1);
2638*9880d681SAndroid Build Coastguard Worker Buf[i] = uint8_t(Value >> (Index * 8));
2639*9880d681SAndroid Build Coastguard Worker }
2640*9880d681SAndroid Build Coastguard Worker assert(ValidReloc.Size <= sizeof(Buf));
2641*9880d681SAndroid Build Coastguard Worker memcpy(&Data[ValidReloc.Offset - BaseOffset], Buf, ValidReloc.Size);
2642*9880d681SAndroid Build Coastguard Worker Applied = true;
2643*9880d681SAndroid Build Coastguard Worker }
2644*9880d681SAndroid Build Coastguard Worker
2645*9880d681SAndroid Build Coastguard Worker return Applied;
2646*9880d681SAndroid Build Coastguard Worker }
2647*9880d681SAndroid Build Coastguard Worker
isTypeTag(uint16_t Tag)2648*9880d681SAndroid Build Coastguard Worker static bool isTypeTag(uint16_t Tag) {
2649*9880d681SAndroid Build Coastguard Worker switch (Tag) {
2650*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_array_type:
2651*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_class_type:
2652*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_enumeration_type:
2653*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_pointer_type:
2654*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_reference_type:
2655*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_string_type:
2656*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_structure_type:
2657*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_subroutine_type:
2658*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_typedef:
2659*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_union_type:
2660*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_ptr_to_member_type:
2661*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_set_type:
2662*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_subrange_type:
2663*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_base_type:
2664*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_const_type:
2665*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_constant:
2666*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_file_type:
2667*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_namelist:
2668*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_packed_type:
2669*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_volatile_type:
2670*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_restrict_type:
2671*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_interface_type:
2672*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_unspecified_type:
2673*9880d681SAndroid Build Coastguard Worker case dwarf::DW_TAG_shared_type:
2674*9880d681SAndroid Build Coastguard Worker return true;
2675*9880d681SAndroid Build Coastguard Worker default:
2676*9880d681SAndroid Build Coastguard Worker break;
2677*9880d681SAndroid Build Coastguard Worker }
2678*9880d681SAndroid Build Coastguard Worker return false;
2679*9880d681SAndroid Build Coastguard Worker }
2680*9880d681SAndroid Build Coastguard Worker
2681*9880d681SAndroid Build Coastguard Worker static bool
shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,uint16_t Tag,bool InDebugMap,bool SkipPC,bool InFunctionScope)2682*9880d681SAndroid Build Coastguard Worker shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
2683*9880d681SAndroid Build Coastguard Worker uint16_t Tag, bool InDebugMap, bool SkipPC,
2684*9880d681SAndroid Build Coastguard Worker bool InFunctionScope) {
2685*9880d681SAndroid Build Coastguard Worker switch (AttrSpec.Attr) {
2686*9880d681SAndroid Build Coastguard Worker default:
2687*9880d681SAndroid Build Coastguard Worker return false;
2688*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_low_pc:
2689*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_high_pc:
2690*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_ranges:
2691*9880d681SAndroid Build Coastguard Worker return SkipPC;
2692*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_location:
2693*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_frame_base:
2694*9880d681SAndroid Build Coastguard Worker // FIXME: for some reason dsymutil-classic keeps the location
2695*9880d681SAndroid Build Coastguard Worker // attributes when they are of block type (ie. not location
2696*9880d681SAndroid Build Coastguard Worker // lists). This is totally wrong for globals where we will keep a
2697*9880d681SAndroid Build Coastguard Worker // wrong address. It is mostly harmless for locals, but there is
2698*9880d681SAndroid Build Coastguard Worker // no point in keeping these anyway when the function wasn't linked.
2699*9880d681SAndroid Build Coastguard Worker return (SkipPC || (!InFunctionScope && Tag == dwarf::DW_TAG_variable &&
2700*9880d681SAndroid Build Coastguard Worker !InDebugMap)) &&
2701*9880d681SAndroid Build Coastguard Worker !DWARFFormValue(AttrSpec.Form).isFormClass(DWARFFormValue::FC_Block);
2702*9880d681SAndroid Build Coastguard Worker }
2703*9880d681SAndroid Build Coastguard Worker }
2704*9880d681SAndroid Build Coastguard Worker
cloneDIE(const DWARFDebugInfoEntryMinimal & InputDIE,CompileUnit & Unit,int64_t PCOffset,uint32_t OutOffset,unsigned Flags)2705*9880d681SAndroid Build Coastguard Worker DIE *DwarfLinker::DIECloner::cloneDIE(
2706*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &InputDIE, CompileUnit &Unit,
2707*9880d681SAndroid Build Coastguard Worker int64_t PCOffset, uint32_t OutOffset, unsigned Flags) {
2708*9880d681SAndroid Build Coastguard Worker DWARFUnit &U = Unit.getOrigUnit();
2709*9880d681SAndroid Build Coastguard Worker unsigned Idx = U.getDIEIndex(&InputDIE);
2710*9880d681SAndroid Build Coastguard Worker CompileUnit::DIEInfo &Info = Unit.getInfo(Idx);
2711*9880d681SAndroid Build Coastguard Worker
2712*9880d681SAndroid Build Coastguard Worker // Should the DIE appear in the output?
2713*9880d681SAndroid Build Coastguard Worker if (!Unit.getInfo(Idx).Keep)
2714*9880d681SAndroid Build Coastguard Worker return nullptr;
2715*9880d681SAndroid Build Coastguard Worker
2716*9880d681SAndroid Build Coastguard Worker uint32_t Offset = InputDIE.getOffset();
2717*9880d681SAndroid Build Coastguard Worker // The DIE might have been already created by a forward reference
2718*9880d681SAndroid Build Coastguard Worker // (see cloneDieReferenceAttribute()).
2719*9880d681SAndroid Build Coastguard Worker DIE *Die = Info.Clone;
2720*9880d681SAndroid Build Coastguard Worker if (!Die)
2721*9880d681SAndroid Build Coastguard Worker Die = Info.Clone = DIE::get(DIEAlloc, dwarf::Tag(InputDIE.getTag()));
2722*9880d681SAndroid Build Coastguard Worker assert(Die->getTag() == InputDIE.getTag());
2723*9880d681SAndroid Build Coastguard Worker Die->setOffset(OutOffset);
2724*9880d681SAndroid Build Coastguard Worker if ((Unit.hasODR() || Unit.isClangModule()) &&
2725*9880d681SAndroid Build Coastguard Worker Die->getTag() != dwarf::DW_TAG_namespace && Info.Ctxt &&
2726*9880d681SAndroid Build Coastguard Worker Info.Ctxt != Unit.getInfo(Info.ParentIdx).Ctxt &&
2727*9880d681SAndroid Build Coastguard Worker !Info.Ctxt->getCanonicalDIEOffset()) {
2728*9880d681SAndroid Build Coastguard Worker // We are about to emit a DIE that is the root of its own valid
2729*9880d681SAndroid Build Coastguard Worker // DeclContext tree. Make the current offset the canonical offset
2730*9880d681SAndroid Build Coastguard Worker // for this context.
2731*9880d681SAndroid Build Coastguard Worker Info.Ctxt->setCanonicalDIEOffset(OutOffset + Unit.getStartOffset());
2732*9880d681SAndroid Build Coastguard Worker }
2733*9880d681SAndroid Build Coastguard Worker
2734*9880d681SAndroid Build Coastguard Worker // Extract and clone every attribute.
2735*9880d681SAndroid Build Coastguard Worker DataExtractor Data = U.getDebugInfoExtractor();
2736*9880d681SAndroid Build Coastguard Worker // Point to the next DIE (generally there is always at least a NULL
2737*9880d681SAndroid Build Coastguard Worker // entry after the current one). If this is a lone
2738*9880d681SAndroid Build Coastguard Worker // DW_TAG_compile_unit without any children, point to the next unit.
2739*9880d681SAndroid Build Coastguard Worker uint32_t NextOffset =
2740*9880d681SAndroid Build Coastguard Worker (Idx + 1 < U.getNumDIEs())
2741*9880d681SAndroid Build Coastguard Worker ? U.getDIEAtIndex(Idx + 1)->getOffset()
2742*9880d681SAndroid Build Coastguard Worker : U.getNextUnitOffset();
2743*9880d681SAndroid Build Coastguard Worker AttributesInfo AttrInfo;
2744*9880d681SAndroid Build Coastguard Worker
2745*9880d681SAndroid Build Coastguard Worker // We could copy the data only if we need to aply a relocation to
2746*9880d681SAndroid Build Coastguard Worker // it. After testing, it seems there is no performance downside to
2747*9880d681SAndroid Build Coastguard Worker // doing the copy unconditionally, and it makes the code simpler.
2748*9880d681SAndroid Build Coastguard Worker SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset - Offset));
2749*9880d681SAndroid Build Coastguard Worker Data = DataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize());
2750*9880d681SAndroid Build Coastguard Worker // Modify the copy with relocated addresses.
2751*9880d681SAndroid Build Coastguard Worker if (RelocMgr.applyValidRelocs(DIECopy, Offset, Data.isLittleEndian())) {
2752*9880d681SAndroid Build Coastguard Worker // If we applied relocations, we store the value of high_pc that was
2753*9880d681SAndroid Build Coastguard Worker // potentially stored in the input DIE. If high_pc is an address
2754*9880d681SAndroid Build Coastguard Worker // (Dwarf version == 2), then it might have been relocated to a
2755*9880d681SAndroid Build Coastguard Worker // totally unrelated value (because the end address in the object
2756*9880d681SAndroid Build Coastguard Worker // file might be start address of another function which got moved
2757*9880d681SAndroid Build Coastguard Worker // independantly by the linker). The computation of the actual
2758*9880d681SAndroid Build Coastguard Worker // high_pc value is done in cloneAddressAttribute().
2759*9880d681SAndroid Build Coastguard Worker AttrInfo.OrigHighPc =
2760*9880d681SAndroid Build Coastguard Worker InputDIE.getAttributeValueAsAddress(&U, dwarf::DW_AT_high_pc, 0);
2761*9880d681SAndroid Build Coastguard Worker // Also store the low_pc. It might get relocated in an
2762*9880d681SAndroid Build Coastguard Worker // inline_subprogram that happens at the beginning of its
2763*9880d681SAndroid Build Coastguard Worker // inlining function.
2764*9880d681SAndroid Build Coastguard Worker AttrInfo.OrigLowPc =
2765*9880d681SAndroid Build Coastguard Worker InputDIE.getAttributeValueAsAddress(&U, dwarf::DW_AT_low_pc, UINT64_MAX);
2766*9880d681SAndroid Build Coastguard Worker }
2767*9880d681SAndroid Build Coastguard Worker
2768*9880d681SAndroid Build Coastguard Worker // Reset the Offset to 0 as we will be working on the local copy of
2769*9880d681SAndroid Build Coastguard Worker // the data.
2770*9880d681SAndroid Build Coastguard Worker Offset = 0;
2771*9880d681SAndroid Build Coastguard Worker
2772*9880d681SAndroid Build Coastguard Worker const auto *Abbrev = InputDIE.getAbbreviationDeclarationPtr();
2773*9880d681SAndroid Build Coastguard Worker Offset += getULEB128Size(Abbrev->getCode());
2774*9880d681SAndroid Build Coastguard Worker
2775*9880d681SAndroid Build Coastguard Worker // We are entering a subprogram. Get and propagate the PCOffset.
2776*9880d681SAndroid Build Coastguard Worker if (Die->getTag() == dwarf::DW_TAG_subprogram)
2777*9880d681SAndroid Build Coastguard Worker PCOffset = Info.AddrAdjust;
2778*9880d681SAndroid Build Coastguard Worker AttrInfo.PCOffset = PCOffset;
2779*9880d681SAndroid Build Coastguard Worker
2780*9880d681SAndroid Build Coastguard Worker if (Abbrev->getTag() == dwarf::DW_TAG_subprogram) {
2781*9880d681SAndroid Build Coastguard Worker Flags |= TF_InFunctionScope;
2782*9880d681SAndroid Build Coastguard Worker if (!Info.InDebugMap)
2783*9880d681SAndroid Build Coastguard Worker Flags |= TF_SkipPC;
2784*9880d681SAndroid Build Coastguard Worker }
2785*9880d681SAndroid Build Coastguard Worker
2786*9880d681SAndroid Build Coastguard Worker bool Copied = false;
2787*9880d681SAndroid Build Coastguard Worker for (const auto &AttrSpec : Abbrev->attributes()) {
2788*9880d681SAndroid Build Coastguard Worker if (shouldSkipAttribute(AttrSpec, Die->getTag(), Info.InDebugMap,
2789*9880d681SAndroid Build Coastguard Worker Flags & TF_SkipPC, Flags & TF_InFunctionScope)) {
2790*9880d681SAndroid Build Coastguard Worker DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset, &U);
2791*9880d681SAndroid Build Coastguard Worker // FIXME: dsymutil-classic keeps the old abbreviation around
2792*9880d681SAndroid Build Coastguard Worker // even if it's not used. We can remove this (and the copyAbbrev
2793*9880d681SAndroid Build Coastguard Worker // helper) as soon as bit-for-bit compatibility is not a goal anymore.
2794*9880d681SAndroid Build Coastguard Worker if (!Copied) {
2795*9880d681SAndroid Build Coastguard Worker copyAbbrev(*InputDIE.getAbbreviationDeclarationPtr(), Unit.hasODR());
2796*9880d681SAndroid Build Coastguard Worker Copied = true;
2797*9880d681SAndroid Build Coastguard Worker }
2798*9880d681SAndroid Build Coastguard Worker continue;
2799*9880d681SAndroid Build Coastguard Worker }
2800*9880d681SAndroid Build Coastguard Worker
2801*9880d681SAndroid Build Coastguard Worker DWARFFormValue Val(AttrSpec.Form);
2802*9880d681SAndroid Build Coastguard Worker uint32_t AttrSize = Offset;
2803*9880d681SAndroid Build Coastguard Worker Val.extractValue(Data, &Offset, &U);
2804*9880d681SAndroid Build Coastguard Worker AttrSize = Offset - AttrSize;
2805*9880d681SAndroid Build Coastguard Worker
2806*9880d681SAndroid Build Coastguard Worker OutOffset +=
2807*9880d681SAndroid Build Coastguard Worker cloneAttribute(*Die, InputDIE, Unit, Val, AttrSpec, AttrSize, AttrInfo);
2808*9880d681SAndroid Build Coastguard Worker }
2809*9880d681SAndroid Build Coastguard Worker
2810*9880d681SAndroid Build Coastguard Worker // Look for accelerator entries.
2811*9880d681SAndroid Build Coastguard Worker uint16_t Tag = InputDIE.getTag();
2812*9880d681SAndroid Build Coastguard Worker // FIXME: This is slightly wrong. An inline_subroutine without a
2813*9880d681SAndroid Build Coastguard Worker // low_pc, but with AT_ranges might be interesting to get into the
2814*9880d681SAndroid Build Coastguard Worker // accelerator tables too. For now stick with dsymutil's behavior.
2815*9880d681SAndroid Build Coastguard Worker if ((Info.InDebugMap || AttrInfo.HasLowPc) &&
2816*9880d681SAndroid Build Coastguard Worker Tag != dwarf::DW_TAG_compile_unit &&
2817*9880d681SAndroid Build Coastguard Worker getDIENames(InputDIE, Unit.getOrigUnit(), AttrInfo)) {
2818*9880d681SAndroid Build Coastguard Worker if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name)
2819*9880d681SAndroid Build Coastguard Worker Unit.addNameAccelerator(Die, AttrInfo.MangledName,
2820*9880d681SAndroid Build Coastguard Worker AttrInfo.MangledNameOffset,
2821*9880d681SAndroid Build Coastguard Worker Tag == dwarf::DW_TAG_inlined_subroutine);
2822*9880d681SAndroid Build Coastguard Worker if (AttrInfo.Name)
2823*9880d681SAndroid Build Coastguard Worker Unit.addNameAccelerator(Die, AttrInfo.Name, AttrInfo.NameOffset,
2824*9880d681SAndroid Build Coastguard Worker Tag == dwarf::DW_TAG_inlined_subroutine);
2825*9880d681SAndroid Build Coastguard Worker } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration &&
2826*9880d681SAndroid Build Coastguard Worker getDIENames(InputDIE, Unit.getOrigUnit(), AttrInfo)) {
2827*9880d681SAndroid Build Coastguard Worker Unit.addTypeAccelerator(Die, AttrInfo.Name, AttrInfo.NameOffset);
2828*9880d681SAndroid Build Coastguard Worker }
2829*9880d681SAndroid Build Coastguard Worker
2830*9880d681SAndroid Build Coastguard Worker // Determine whether there are any children that we want to keep.
2831*9880d681SAndroid Build Coastguard Worker bool HasChildren = false;
2832*9880d681SAndroid Build Coastguard Worker for (auto *Child = InputDIE.getFirstChild(); Child && !Child->isNULL();
2833*9880d681SAndroid Build Coastguard Worker Child = Child->getSibling()) {
2834*9880d681SAndroid Build Coastguard Worker unsigned Idx = U.getDIEIndex(Child);
2835*9880d681SAndroid Build Coastguard Worker if (Unit.getInfo(Idx).Keep) {
2836*9880d681SAndroid Build Coastguard Worker HasChildren = true;
2837*9880d681SAndroid Build Coastguard Worker break;
2838*9880d681SAndroid Build Coastguard Worker }
2839*9880d681SAndroid Build Coastguard Worker }
2840*9880d681SAndroid Build Coastguard Worker
2841*9880d681SAndroid Build Coastguard Worker DIEAbbrev NewAbbrev = Die->generateAbbrev();
2842*9880d681SAndroid Build Coastguard Worker if (HasChildren)
2843*9880d681SAndroid Build Coastguard Worker NewAbbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
2844*9880d681SAndroid Build Coastguard Worker // Assign a permanent abbrev number
2845*9880d681SAndroid Build Coastguard Worker Linker.AssignAbbrev(NewAbbrev);
2846*9880d681SAndroid Build Coastguard Worker Die->setAbbrevNumber(NewAbbrev.getNumber());
2847*9880d681SAndroid Build Coastguard Worker
2848*9880d681SAndroid Build Coastguard Worker // Add the size of the abbreviation number to the output offset.
2849*9880d681SAndroid Build Coastguard Worker OutOffset += getULEB128Size(Die->getAbbrevNumber());
2850*9880d681SAndroid Build Coastguard Worker
2851*9880d681SAndroid Build Coastguard Worker if (!HasChildren) {
2852*9880d681SAndroid Build Coastguard Worker // Update our size.
2853*9880d681SAndroid Build Coastguard Worker Die->setSize(OutOffset - Die->getOffset());
2854*9880d681SAndroid Build Coastguard Worker return Die;
2855*9880d681SAndroid Build Coastguard Worker }
2856*9880d681SAndroid Build Coastguard Worker
2857*9880d681SAndroid Build Coastguard Worker // Recursively clone children.
2858*9880d681SAndroid Build Coastguard Worker for (auto *Child = InputDIE.getFirstChild(); Child && !Child->isNULL();
2859*9880d681SAndroid Build Coastguard Worker Child = Child->getSibling()) {
2860*9880d681SAndroid Build Coastguard Worker if (DIE *Clone = cloneDIE(*Child, Unit, PCOffset, OutOffset, Flags)) {
2861*9880d681SAndroid Build Coastguard Worker Die->addChild(Clone);
2862*9880d681SAndroid Build Coastguard Worker OutOffset = Clone->getOffset() + Clone->getSize();
2863*9880d681SAndroid Build Coastguard Worker }
2864*9880d681SAndroid Build Coastguard Worker }
2865*9880d681SAndroid Build Coastguard Worker
2866*9880d681SAndroid Build Coastguard Worker // Account for the end of children marker.
2867*9880d681SAndroid Build Coastguard Worker OutOffset += sizeof(int8_t);
2868*9880d681SAndroid Build Coastguard Worker // Update our size.
2869*9880d681SAndroid Build Coastguard Worker Die->setSize(OutOffset - Die->getOffset());
2870*9880d681SAndroid Build Coastguard Worker return Die;
2871*9880d681SAndroid Build Coastguard Worker }
2872*9880d681SAndroid Build Coastguard Worker
2873*9880d681SAndroid Build Coastguard Worker /// \brief Patch the input object file relevant debug_ranges entries
2874*9880d681SAndroid Build Coastguard Worker /// and emit them in the output file. Update the relevant attributes
2875*9880d681SAndroid Build Coastguard Worker /// to point at the new entries.
patchRangesForUnit(const CompileUnit & Unit,DWARFContext & OrigDwarf) const2876*9880d681SAndroid Build Coastguard Worker void DwarfLinker::patchRangesForUnit(const CompileUnit &Unit,
2877*9880d681SAndroid Build Coastguard Worker DWARFContext &OrigDwarf) const {
2878*9880d681SAndroid Build Coastguard Worker DWARFDebugRangeList RangeList;
2879*9880d681SAndroid Build Coastguard Worker const auto &FunctionRanges = Unit.getFunctionRanges();
2880*9880d681SAndroid Build Coastguard Worker unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
2881*9880d681SAndroid Build Coastguard Worker DataExtractor RangeExtractor(OrigDwarf.getRangeSection(),
2882*9880d681SAndroid Build Coastguard Worker OrigDwarf.isLittleEndian(), AddressSize);
2883*9880d681SAndroid Build Coastguard Worker auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;
2884*9880d681SAndroid Build Coastguard Worker DWARFUnit &OrigUnit = Unit.getOrigUnit();
2885*9880d681SAndroid Build Coastguard Worker const auto *OrigUnitDie = OrigUnit.getUnitDIE(false);
2886*9880d681SAndroid Build Coastguard Worker uint64_t OrigLowPc = OrigUnitDie->getAttributeValueAsAddress(
2887*9880d681SAndroid Build Coastguard Worker &OrigUnit, dwarf::DW_AT_low_pc, -1ULL);
2888*9880d681SAndroid Build Coastguard Worker // Ranges addresses are based on the unit's low_pc. Compute the
2889*9880d681SAndroid Build Coastguard Worker // offset we need to apply to adapt to the new unit's low_pc.
2890*9880d681SAndroid Build Coastguard Worker int64_t UnitPcOffset = 0;
2891*9880d681SAndroid Build Coastguard Worker if (OrigLowPc != -1ULL)
2892*9880d681SAndroid Build Coastguard Worker UnitPcOffset = int64_t(OrigLowPc) - Unit.getLowPc();
2893*9880d681SAndroid Build Coastguard Worker
2894*9880d681SAndroid Build Coastguard Worker for (const auto &RangeAttribute : Unit.getRangesAttributes()) {
2895*9880d681SAndroid Build Coastguard Worker uint32_t Offset = RangeAttribute.get();
2896*9880d681SAndroid Build Coastguard Worker RangeAttribute.set(Streamer->getRangesSectionSize());
2897*9880d681SAndroid Build Coastguard Worker RangeList.extract(RangeExtractor, &Offset);
2898*9880d681SAndroid Build Coastguard Worker const auto &Entries = RangeList.getEntries();
2899*9880d681SAndroid Build Coastguard Worker if (!Entries.empty()) {
2900*9880d681SAndroid Build Coastguard Worker const DWARFDebugRangeList::RangeListEntry &First = Entries.front();
2901*9880d681SAndroid Build Coastguard Worker
2902*9880d681SAndroid Build Coastguard Worker if (CurrRange == InvalidRange ||
2903*9880d681SAndroid Build Coastguard Worker First.StartAddress + OrigLowPc < CurrRange.start() ||
2904*9880d681SAndroid Build Coastguard Worker First.StartAddress + OrigLowPc >= CurrRange.stop()) {
2905*9880d681SAndroid Build Coastguard Worker CurrRange = FunctionRanges.find(First.StartAddress + OrigLowPc);
2906*9880d681SAndroid Build Coastguard Worker if (CurrRange == InvalidRange ||
2907*9880d681SAndroid Build Coastguard Worker CurrRange.start() > First.StartAddress + OrigLowPc) {
2908*9880d681SAndroid Build Coastguard Worker reportWarning("no mapping for range.");
2909*9880d681SAndroid Build Coastguard Worker continue;
2910*9880d681SAndroid Build Coastguard Worker }
2911*9880d681SAndroid Build Coastguard Worker }
2912*9880d681SAndroid Build Coastguard Worker }
2913*9880d681SAndroid Build Coastguard Worker
2914*9880d681SAndroid Build Coastguard Worker Streamer->emitRangesEntries(UnitPcOffset, OrigLowPc, CurrRange, Entries,
2915*9880d681SAndroid Build Coastguard Worker AddressSize);
2916*9880d681SAndroid Build Coastguard Worker }
2917*9880d681SAndroid Build Coastguard Worker }
2918*9880d681SAndroid Build Coastguard Worker
2919*9880d681SAndroid Build Coastguard Worker /// \brief Generate the debug_aranges entries for \p Unit and if the
2920*9880d681SAndroid Build Coastguard Worker /// unit has a DW_AT_ranges attribute, also emit the debug_ranges
2921*9880d681SAndroid Build Coastguard Worker /// contribution for this attribute.
2922*9880d681SAndroid Build Coastguard Worker /// FIXME: this could actually be done right in patchRangesForUnit,
2923*9880d681SAndroid Build Coastguard Worker /// but for the sake of initial bit-for-bit compatibility with legacy
2924*9880d681SAndroid Build Coastguard Worker /// dsymutil, we have to do it in a delayed pass.
generateUnitRanges(CompileUnit & Unit) const2925*9880d681SAndroid Build Coastguard Worker void DwarfLinker::generateUnitRanges(CompileUnit &Unit) const {
2926*9880d681SAndroid Build Coastguard Worker auto Attr = Unit.getUnitRangesAttribute();
2927*9880d681SAndroid Build Coastguard Worker if (Attr)
2928*9880d681SAndroid Build Coastguard Worker Attr->set(Streamer->getRangesSectionSize());
2929*9880d681SAndroid Build Coastguard Worker Streamer->emitUnitRangesEntries(Unit, static_cast<bool>(Attr));
2930*9880d681SAndroid Build Coastguard Worker }
2931*9880d681SAndroid Build Coastguard Worker
2932*9880d681SAndroid Build Coastguard Worker /// \brief Insert the new line info sequence \p Seq into the current
2933*9880d681SAndroid Build Coastguard Worker /// set of already linked line info \p Rows.
insertLineSequence(std::vector<DWARFDebugLine::Row> & Seq,std::vector<DWARFDebugLine::Row> & Rows)2934*9880d681SAndroid Build Coastguard Worker static void insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
2935*9880d681SAndroid Build Coastguard Worker std::vector<DWARFDebugLine::Row> &Rows) {
2936*9880d681SAndroid Build Coastguard Worker if (Seq.empty())
2937*9880d681SAndroid Build Coastguard Worker return;
2938*9880d681SAndroid Build Coastguard Worker
2939*9880d681SAndroid Build Coastguard Worker if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
2940*9880d681SAndroid Build Coastguard Worker Rows.insert(Rows.end(), Seq.begin(), Seq.end());
2941*9880d681SAndroid Build Coastguard Worker Seq.clear();
2942*9880d681SAndroid Build Coastguard Worker return;
2943*9880d681SAndroid Build Coastguard Worker }
2944*9880d681SAndroid Build Coastguard Worker
2945*9880d681SAndroid Build Coastguard Worker auto InsertPoint = std::lower_bound(
2946*9880d681SAndroid Build Coastguard Worker Rows.begin(), Rows.end(), Seq.front(),
2947*9880d681SAndroid Build Coastguard Worker [](const DWARFDebugLine::Row &LHS, const DWARFDebugLine::Row &RHS) {
2948*9880d681SAndroid Build Coastguard Worker return LHS.Address < RHS.Address;
2949*9880d681SAndroid Build Coastguard Worker });
2950*9880d681SAndroid Build Coastguard Worker
2951*9880d681SAndroid Build Coastguard Worker // FIXME: this only removes the unneeded end_sequence if the
2952*9880d681SAndroid Build Coastguard Worker // sequences have been inserted in order. using a global sort like
2953*9880d681SAndroid Build Coastguard Worker // described in patchLineTableForUnit() and delaying the end_sequene
2954*9880d681SAndroid Build Coastguard Worker // elimination to emitLineTableForUnit() we can get rid of all of them.
2955*9880d681SAndroid Build Coastguard Worker if (InsertPoint != Rows.end() &&
2956*9880d681SAndroid Build Coastguard Worker InsertPoint->Address == Seq.front().Address && InsertPoint->EndSequence) {
2957*9880d681SAndroid Build Coastguard Worker *InsertPoint = Seq.front();
2958*9880d681SAndroid Build Coastguard Worker Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
2959*9880d681SAndroid Build Coastguard Worker } else {
2960*9880d681SAndroid Build Coastguard Worker Rows.insert(InsertPoint, Seq.begin(), Seq.end());
2961*9880d681SAndroid Build Coastguard Worker }
2962*9880d681SAndroid Build Coastguard Worker
2963*9880d681SAndroid Build Coastguard Worker Seq.clear();
2964*9880d681SAndroid Build Coastguard Worker }
2965*9880d681SAndroid Build Coastguard Worker
patchStmtList(DIE & Die,DIEInteger Offset)2966*9880d681SAndroid Build Coastguard Worker static void patchStmtList(DIE &Die, DIEInteger Offset) {
2967*9880d681SAndroid Build Coastguard Worker for (auto &V : Die.values())
2968*9880d681SAndroid Build Coastguard Worker if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
2969*9880d681SAndroid Build Coastguard Worker V = DIEValue(V.getAttribute(), V.getForm(), Offset);
2970*9880d681SAndroid Build Coastguard Worker return;
2971*9880d681SAndroid Build Coastguard Worker }
2972*9880d681SAndroid Build Coastguard Worker
2973*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Didn't find DW_AT_stmt_list in cloned DIE!");
2974*9880d681SAndroid Build Coastguard Worker }
2975*9880d681SAndroid Build Coastguard Worker
2976*9880d681SAndroid Build Coastguard Worker /// \brief Extract the line table for \p Unit from \p OrigDwarf, and
2977*9880d681SAndroid Build Coastguard Worker /// recreate a relocated version of these for the address ranges that
2978*9880d681SAndroid Build Coastguard Worker /// are present in the binary.
patchLineTableForUnit(CompileUnit & Unit,DWARFContext & OrigDwarf)2979*9880d681SAndroid Build Coastguard Worker void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
2980*9880d681SAndroid Build Coastguard Worker DWARFContext &OrigDwarf) {
2981*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal *CUDie = Unit.getOrigUnit().getUnitDIE();
2982*9880d681SAndroid Build Coastguard Worker uint64_t StmtList = CUDie->getAttributeValueAsSectionOffset(
2983*9880d681SAndroid Build Coastguard Worker &Unit.getOrigUnit(), dwarf::DW_AT_stmt_list, -1ULL);
2984*9880d681SAndroid Build Coastguard Worker if (StmtList == -1ULL)
2985*9880d681SAndroid Build Coastguard Worker return;
2986*9880d681SAndroid Build Coastguard Worker
2987*9880d681SAndroid Build Coastguard Worker // Update the cloned DW_AT_stmt_list with the correct debug_line offset.
2988*9880d681SAndroid Build Coastguard Worker if (auto *OutputDIE = Unit.getOutputUnitDIE())
2989*9880d681SAndroid Build Coastguard Worker patchStmtList(*OutputDIE, DIEInteger(Streamer->getLineSectionSize()));
2990*9880d681SAndroid Build Coastguard Worker
2991*9880d681SAndroid Build Coastguard Worker // Parse the original line info for the unit.
2992*9880d681SAndroid Build Coastguard Worker DWARFDebugLine::LineTable LineTable;
2993*9880d681SAndroid Build Coastguard Worker uint32_t StmtOffset = StmtList;
2994*9880d681SAndroid Build Coastguard Worker StringRef LineData = OrigDwarf.getLineSection().Data;
2995*9880d681SAndroid Build Coastguard Worker DataExtractor LineExtractor(LineData, OrigDwarf.isLittleEndian(),
2996*9880d681SAndroid Build Coastguard Worker Unit.getOrigUnit().getAddressByteSize());
2997*9880d681SAndroid Build Coastguard Worker LineTable.parse(LineExtractor, &OrigDwarf.getLineSection().Relocs,
2998*9880d681SAndroid Build Coastguard Worker &StmtOffset);
2999*9880d681SAndroid Build Coastguard Worker
3000*9880d681SAndroid Build Coastguard Worker // This vector is the output line table.
3001*9880d681SAndroid Build Coastguard Worker std::vector<DWARFDebugLine::Row> NewRows;
3002*9880d681SAndroid Build Coastguard Worker NewRows.reserve(LineTable.Rows.size());
3003*9880d681SAndroid Build Coastguard Worker
3004*9880d681SAndroid Build Coastguard Worker // Current sequence of rows being extracted, before being inserted
3005*9880d681SAndroid Build Coastguard Worker // in NewRows.
3006*9880d681SAndroid Build Coastguard Worker std::vector<DWARFDebugLine::Row> Seq;
3007*9880d681SAndroid Build Coastguard Worker const auto &FunctionRanges = Unit.getFunctionRanges();
3008*9880d681SAndroid Build Coastguard Worker auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;
3009*9880d681SAndroid Build Coastguard Worker
3010*9880d681SAndroid Build Coastguard Worker // FIXME: This logic is meant to generate exactly the same output as
3011*9880d681SAndroid Build Coastguard Worker // Darwin's classic dsynutil. There is a nicer way to implement this
3012*9880d681SAndroid Build Coastguard Worker // by simply putting all the relocated line info in NewRows and simply
3013*9880d681SAndroid Build Coastguard Worker // sorting NewRows before passing it to emitLineTableForUnit. This
3014*9880d681SAndroid Build Coastguard Worker // should be correct as sequences for a function should stay
3015*9880d681SAndroid Build Coastguard Worker // together in the sorted output. There are a few corner cases that
3016*9880d681SAndroid Build Coastguard Worker // look suspicious though, and that required to implement the logic
3017*9880d681SAndroid Build Coastguard Worker // this way. Revisit that once initial validation is finished.
3018*9880d681SAndroid Build Coastguard Worker
3019*9880d681SAndroid Build Coastguard Worker // Iterate over the object file line info and extract the sequences
3020*9880d681SAndroid Build Coastguard Worker // that correspond to linked functions.
3021*9880d681SAndroid Build Coastguard Worker for (auto &Row : LineTable.Rows) {
3022*9880d681SAndroid Build Coastguard Worker // Check wether we stepped out of the range. The range is
3023*9880d681SAndroid Build Coastguard Worker // half-open, but consider accept the end address of the range if
3024*9880d681SAndroid Build Coastguard Worker // it is marked as end_sequence in the input (because in that
3025*9880d681SAndroid Build Coastguard Worker // case, the relocation offset is accurate and that entry won't
3026*9880d681SAndroid Build Coastguard Worker // serve as the start of another function).
3027*9880d681SAndroid Build Coastguard Worker if (CurrRange == InvalidRange || Row.Address < CurrRange.start() ||
3028*9880d681SAndroid Build Coastguard Worker Row.Address > CurrRange.stop() ||
3029*9880d681SAndroid Build Coastguard Worker (Row.Address == CurrRange.stop() && !Row.EndSequence)) {
3030*9880d681SAndroid Build Coastguard Worker // We just stepped out of a known range. Insert a end_sequence
3031*9880d681SAndroid Build Coastguard Worker // corresponding to the end of the range.
3032*9880d681SAndroid Build Coastguard Worker uint64_t StopAddress = CurrRange != InvalidRange
3033*9880d681SAndroid Build Coastguard Worker ? CurrRange.stop() + CurrRange.value()
3034*9880d681SAndroid Build Coastguard Worker : -1ULL;
3035*9880d681SAndroid Build Coastguard Worker CurrRange = FunctionRanges.find(Row.Address);
3036*9880d681SAndroid Build Coastguard Worker bool CurrRangeValid =
3037*9880d681SAndroid Build Coastguard Worker CurrRange != InvalidRange && CurrRange.start() <= Row.Address;
3038*9880d681SAndroid Build Coastguard Worker if (!CurrRangeValid) {
3039*9880d681SAndroid Build Coastguard Worker CurrRange = InvalidRange;
3040*9880d681SAndroid Build Coastguard Worker if (StopAddress != -1ULL) {
3041*9880d681SAndroid Build Coastguard Worker // Try harder by looking in the DebugMapObject function
3042*9880d681SAndroid Build Coastguard Worker // ranges map. There are corner cases where this finds a
3043*9880d681SAndroid Build Coastguard Worker // valid entry. It's unclear if this is right or wrong, but
3044*9880d681SAndroid Build Coastguard Worker // for now do as dsymutil.
3045*9880d681SAndroid Build Coastguard Worker // FIXME: Understand exactly what cases this addresses and
3046*9880d681SAndroid Build Coastguard Worker // potentially remove it along with the Ranges map.
3047*9880d681SAndroid Build Coastguard Worker auto Range = Ranges.lower_bound(Row.Address);
3048*9880d681SAndroid Build Coastguard Worker if (Range != Ranges.begin() && Range != Ranges.end())
3049*9880d681SAndroid Build Coastguard Worker --Range;
3050*9880d681SAndroid Build Coastguard Worker
3051*9880d681SAndroid Build Coastguard Worker if (Range != Ranges.end() && Range->first <= Row.Address &&
3052*9880d681SAndroid Build Coastguard Worker Range->second.first >= Row.Address) {
3053*9880d681SAndroid Build Coastguard Worker StopAddress = Row.Address + Range->second.second;
3054*9880d681SAndroid Build Coastguard Worker }
3055*9880d681SAndroid Build Coastguard Worker }
3056*9880d681SAndroid Build Coastguard Worker }
3057*9880d681SAndroid Build Coastguard Worker if (StopAddress != -1ULL && !Seq.empty()) {
3058*9880d681SAndroid Build Coastguard Worker // Insert end sequence row with the computed end address, but
3059*9880d681SAndroid Build Coastguard Worker // the same line as the previous one.
3060*9880d681SAndroid Build Coastguard Worker auto NextLine = Seq.back();
3061*9880d681SAndroid Build Coastguard Worker NextLine.Address = StopAddress;
3062*9880d681SAndroid Build Coastguard Worker NextLine.EndSequence = 1;
3063*9880d681SAndroid Build Coastguard Worker NextLine.PrologueEnd = 0;
3064*9880d681SAndroid Build Coastguard Worker NextLine.BasicBlock = 0;
3065*9880d681SAndroid Build Coastguard Worker NextLine.EpilogueBegin = 0;
3066*9880d681SAndroid Build Coastguard Worker Seq.push_back(NextLine);
3067*9880d681SAndroid Build Coastguard Worker insertLineSequence(Seq, NewRows);
3068*9880d681SAndroid Build Coastguard Worker }
3069*9880d681SAndroid Build Coastguard Worker
3070*9880d681SAndroid Build Coastguard Worker if (!CurrRangeValid)
3071*9880d681SAndroid Build Coastguard Worker continue;
3072*9880d681SAndroid Build Coastguard Worker }
3073*9880d681SAndroid Build Coastguard Worker
3074*9880d681SAndroid Build Coastguard Worker // Ignore empty sequences.
3075*9880d681SAndroid Build Coastguard Worker if (Row.EndSequence && Seq.empty())
3076*9880d681SAndroid Build Coastguard Worker continue;
3077*9880d681SAndroid Build Coastguard Worker
3078*9880d681SAndroid Build Coastguard Worker // Relocate row address and add it to the current sequence.
3079*9880d681SAndroid Build Coastguard Worker Row.Address += CurrRange.value();
3080*9880d681SAndroid Build Coastguard Worker Seq.emplace_back(Row);
3081*9880d681SAndroid Build Coastguard Worker
3082*9880d681SAndroid Build Coastguard Worker if (Row.EndSequence)
3083*9880d681SAndroid Build Coastguard Worker insertLineSequence(Seq, NewRows);
3084*9880d681SAndroid Build Coastguard Worker }
3085*9880d681SAndroid Build Coastguard Worker
3086*9880d681SAndroid Build Coastguard Worker // Finished extracting, now emit the line tables.
3087*9880d681SAndroid Build Coastguard Worker uint32_t PrologueEnd = StmtList + 10 + LineTable.Prologue.PrologueLength;
3088*9880d681SAndroid Build Coastguard Worker // FIXME: LLVM hardcodes it's prologue values. We just copy the
3089*9880d681SAndroid Build Coastguard Worker // prologue over and that works because we act as both producer and
3090*9880d681SAndroid Build Coastguard Worker // consumer. It would be nicer to have a real configurable line
3091*9880d681SAndroid Build Coastguard Worker // table emitter.
3092*9880d681SAndroid Build Coastguard Worker if (LineTable.Prologue.Version != 2 ||
3093*9880d681SAndroid Build Coastguard Worker LineTable.Prologue.DefaultIsStmt != DWARF2_LINE_DEFAULT_IS_STMT ||
3094*9880d681SAndroid Build Coastguard Worker LineTable.Prologue.OpcodeBase > 13)
3095*9880d681SAndroid Build Coastguard Worker reportWarning("line table paramters mismatch. Cannot emit.");
3096*9880d681SAndroid Build Coastguard Worker else {
3097*9880d681SAndroid Build Coastguard Worker MCDwarfLineTableParams Params;
3098*9880d681SAndroid Build Coastguard Worker Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
3099*9880d681SAndroid Build Coastguard Worker Params.DWARF2LineBase = LineTable.Prologue.LineBase;
3100*9880d681SAndroid Build Coastguard Worker Params.DWARF2LineRange = LineTable.Prologue.LineRange;
3101*9880d681SAndroid Build Coastguard Worker Streamer->emitLineTableForUnit(Params,
3102*9880d681SAndroid Build Coastguard Worker LineData.slice(StmtList + 4, PrologueEnd),
3103*9880d681SAndroid Build Coastguard Worker LineTable.Prologue.MinInstLength, NewRows,
3104*9880d681SAndroid Build Coastguard Worker Unit.getOrigUnit().getAddressByteSize());
3105*9880d681SAndroid Build Coastguard Worker }
3106*9880d681SAndroid Build Coastguard Worker }
3107*9880d681SAndroid Build Coastguard Worker
emitAcceleratorEntriesForUnit(CompileUnit & Unit)3108*9880d681SAndroid Build Coastguard Worker void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
3109*9880d681SAndroid Build Coastguard Worker Streamer->emitPubNamesForUnit(Unit);
3110*9880d681SAndroid Build Coastguard Worker Streamer->emitPubTypesForUnit(Unit);
3111*9880d681SAndroid Build Coastguard Worker }
3112*9880d681SAndroid Build Coastguard Worker
3113*9880d681SAndroid Build Coastguard Worker /// \brief Read the frame info stored in the object, and emit the
3114*9880d681SAndroid Build Coastguard Worker /// patched frame descriptions for the linked binary.
3115*9880d681SAndroid Build Coastguard Worker ///
3116*9880d681SAndroid Build Coastguard Worker /// This is actually pretty easy as the data of the CIEs and FDEs can
3117*9880d681SAndroid Build Coastguard Worker /// be considered as black boxes and moved as is. The only thing to do
3118*9880d681SAndroid Build Coastguard Worker /// is to patch the addresses in the headers.
patchFrameInfoForObject(const DebugMapObject & DMO,DWARFContext & OrigDwarf,unsigned AddrSize)3119*9880d681SAndroid Build Coastguard Worker void DwarfLinker::patchFrameInfoForObject(const DebugMapObject &DMO,
3120*9880d681SAndroid Build Coastguard Worker DWARFContext &OrigDwarf,
3121*9880d681SAndroid Build Coastguard Worker unsigned AddrSize) {
3122*9880d681SAndroid Build Coastguard Worker StringRef FrameData = OrigDwarf.getDebugFrameSection();
3123*9880d681SAndroid Build Coastguard Worker if (FrameData.empty())
3124*9880d681SAndroid Build Coastguard Worker return;
3125*9880d681SAndroid Build Coastguard Worker
3126*9880d681SAndroid Build Coastguard Worker DataExtractor Data(FrameData, OrigDwarf.isLittleEndian(), 0);
3127*9880d681SAndroid Build Coastguard Worker uint32_t InputOffset = 0;
3128*9880d681SAndroid Build Coastguard Worker
3129*9880d681SAndroid Build Coastguard Worker // Store the data of the CIEs defined in this object, keyed by their
3130*9880d681SAndroid Build Coastguard Worker // offsets.
3131*9880d681SAndroid Build Coastguard Worker DenseMap<uint32_t, StringRef> LocalCIES;
3132*9880d681SAndroid Build Coastguard Worker
3133*9880d681SAndroid Build Coastguard Worker while (Data.isValidOffset(InputOffset)) {
3134*9880d681SAndroid Build Coastguard Worker uint32_t EntryOffset = InputOffset;
3135*9880d681SAndroid Build Coastguard Worker uint32_t InitialLength = Data.getU32(&InputOffset);
3136*9880d681SAndroid Build Coastguard Worker if (InitialLength == 0xFFFFFFFF)
3137*9880d681SAndroid Build Coastguard Worker return reportWarning("Dwarf64 bits no supported");
3138*9880d681SAndroid Build Coastguard Worker
3139*9880d681SAndroid Build Coastguard Worker uint32_t CIEId = Data.getU32(&InputOffset);
3140*9880d681SAndroid Build Coastguard Worker if (CIEId == 0xFFFFFFFF) {
3141*9880d681SAndroid Build Coastguard Worker // This is a CIE, store it.
3142*9880d681SAndroid Build Coastguard Worker StringRef CIEData = FrameData.substr(EntryOffset, InitialLength + 4);
3143*9880d681SAndroid Build Coastguard Worker LocalCIES[EntryOffset] = CIEData;
3144*9880d681SAndroid Build Coastguard Worker // The -4 is to account for the CIEId we just read.
3145*9880d681SAndroid Build Coastguard Worker InputOffset += InitialLength - 4;
3146*9880d681SAndroid Build Coastguard Worker continue;
3147*9880d681SAndroid Build Coastguard Worker }
3148*9880d681SAndroid Build Coastguard Worker
3149*9880d681SAndroid Build Coastguard Worker uint32_t Loc = Data.getUnsigned(&InputOffset, AddrSize);
3150*9880d681SAndroid Build Coastguard Worker
3151*9880d681SAndroid Build Coastguard Worker // Some compilers seem to emit frame info that doesn't start at
3152*9880d681SAndroid Build Coastguard Worker // the function entry point, thus we can't just lookup the address
3153*9880d681SAndroid Build Coastguard Worker // in the debug map. Use the linker's range map to see if the FDE
3154*9880d681SAndroid Build Coastguard Worker // describes something that we can relocate.
3155*9880d681SAndroid Build Coastguard Worker auto Range = Ranges.upper_bound(Loc);
3156*9880d681SAndroid Build Coastguard Worker if (Range != Ranges.begin())
3157*9880d681SAndroid Build Coastguard Worker --Range;
3158*9880d681SAndroid Build Coastguard Worker if (Range == Ranges.end() || Range->first > Loc ||
3159*9880d681SAndroid Build Coastguard Worker Range->second.first <= Loc) {
3160*9880d681SAndroid Build Coastguard Worker // The +4 is to account for the size of the InitialLength field itself.
3161*9880d681SAndroid Build Coastguard Worker InputOffset = EntryOffset + InitialLength + 4;
3162*9880d681SAndroid Build Coastguard Worker continue;
3163*9880d681SAndroid Build Coastguard Worker }
3164*9880d681SAndroid Build Coastguard Worker
3165*9880d681SAndroid Build Coastguard Worker // This is an FDE, and we have a mapping.
3166*9880d681SAndroid Build Coastguard Worker // Have we already emitted a corresponding CIE?
3167*9880d681SAndroid Build Coastguard Worker StringRef CIEData = LocalCIES[CIEId];
3168*9880d681SAndroid Build Coastguard Worker if (CIEData.empty())
3169*9880d681SAndroid Build Coastguard Worker return reportWarning("Inconsistent debug_frame content. Dropping.");
3170*9880d681SAndroid Build Coastguard Worker
3171*9880d681SAndroid Build Coastguard Worker // Look if we already emitted a CIE that corresponds to the
3172*9880d681SAndroid Build Coastguard Worker // referenced one (the CIE data is the key of that lookup).
3173*9880d681SAndroid Build Coastguard Worker auto IteratorInserted = EmittedCIEs.insert(
3174*9880d681SAndroid Build Coastguard Worker std::make_pair(CIEData, Streamer->getFrameSectionSize()));
3175*9880d681SAndroid Build Coastguard Worker // If there is no CIE yet for this ID, emit it.
3176*9880d681SAndroid Build Coastguard Worker if (IteratorInserted.second ||
3177*9880d681SAndroid Build Coastguard Worker // FIXME: dsymutil-classic only caches the last used CIE for
3178*9880d681SAndroid Build Coastguard Worker // reuse. Mimic that behavior for now. Just removing that
3179*9880d681SAndroid Build Coastguard Worker // second half of the condition and the LastCIEOffset variable
3180*9880d681SAndroid Build Coastguard Worker // makes the code DTRT.
3181*9880d681SAndroid Build Coastguard Worker LastCIEOffset != IteratorInserted.first->getValue()) {
3182*9880d681SAndroid Build Coastguard Worker LastCIEOffset = Streamer->getFrameSectionSize();
3183*9880d681SAndroid Build Coastguard Worker IteratorInserted.first->getValue() = LastCIEOffset;
3184*9880d681SAndroid Build Coastguard Worker Streamer->emitCIE(CIEData);
3185*9880d681SAndroid Build Coastguard Worker }
3186*9880d681SAndroid Build Coastguard Worker
3187*9880d681SAndroid Build Coastguard Worker // Emit the FDE with updated address and CIE pointer.
3188*9880d681SAndroid Build Coastguard Worker // (4 + AddrSize) is the size of the CIEId + initial_location
3189*9880d681SAndroid Build Coastguard Worker // fields that will get reconstructed by emitFDE().
3190*9880d681SAndroid Build Coastguard Worker unsigned FDERemainingBytes = InitialLength - (4 + AddrSize);
3191*9880d681SAndroid Build Coastguard Worker Streamer->emitFDE(IteratorInserted.first->getValue(), AddrSize,
3192*9880d681SAndroid Build Coastguard Worker Loc + Range->second.second,
3193*9880d681SAndroid Build Coastguard Worker FrameData.substr(InputOffset, FDERemainingBytes));
3194*9880d681SAndroid Build Coastguard Worker InputOffset += FDERemainingBytes;
3195*9880d681SAndroid Build Coastguard Worker }
3196*9880d681SAndroid Build Coastguard Worker }
3197*9880d681SAndroid Build Coastguard Worker
copyAbbrev(const DWARFAbbreviationDeclaration & Abbrev,bool hasODR)3198*9880d681SAndroid Build Coastguard Worker void DwarfLinker::DIECloner::copyAbbrev(
3199*9880d681SAndroid Build Coastguard Worker const DWARFAbbreviationDeclaration &Abbrev, bool hasODR) {
3200*9880d681SAndroid Build Coastguard Worker DIEAbbrev Copy(dwarf::Tag(Abbrev.getTag()),
3201*9880d681SAndroid Build Coastguard Worker dwarf::Form(Abbrev.hasChildren()));
3202*9880d681SAndroid Build Coastguard Worker
3203*9880d681SAndroid Build Coastguard Worker for (const auto &Attr : Abbrev.attributes()) {
3204*9880d681SAndroid Build Coastguard Worker uint16_t Form = Attr.Form;
3205*9880d681SAndroid Build Coastguard Worker if (hasODR && isODRAttribute(Attr.Attr))
3206*9880d681SAndroid Build Coastguard Worker Form = dwarf::DW_FORM_ref_addr;
3207*9880d681SAndroid Build Coastguard Worker Copy.AddAttribute(dwarf::Attribute(Attr.Attr), dwarf::Form(Form));
3208*9880d681SAndroid Build Coastguard Worker }
3209*9880d681SAndroid Build Coastguard Worker
3210*9880d681SAndroid Build Coastguard Worker Linker.AssignAbbrev(Copy);
3211*9880d681SAndroid Build Coastguard Worker }
3212*9880d681SAndroid Build Coastguard Worker
getDwoId(const DWARFDebugInfoEntryMinimal & CUDie,const DWARFUnit & Unit)3213*9880d681SAndroid Build Coastguard Worker static uint64_t getDwoId(const DWARFDebugInfoEntryMinimal &CUDie,
3214*9880d681SAndroid Build Coastguard Worker const DWARFUnit &Unit) {
3215*9880d681SAndroid Build Coastguard Worker uint64_t DwoId =
3216*9880d681SAndroid Build Coastguard Worker CUDie.getAttributeValueAsUnsignedConstant(&Unit, dwarf::DW_AT_dwo_id, 0);
3217*9880d681SAndroid Build Coastguard Worker if (!DwoId)
3218*9880d681SAndroid Build Coastguard Worker DwoId = CUDie.getAttributeValueAsUnsignedConstant(&Unit,
3219*9880d681SAndroid Build Coastguard Worker dwarf::DW_AT_GNU_dwo_id, 0);
3220*9880d681SAndroid Build Coastguard Worker return DwoId;
3221*9880d681SAndroid Build Coastguard Worker }
3222*9880d681SAndroid Build Coastguard Worker
registerModuleReference(const DWARFDebugInfoEntryMinimal & CUDie,const DWARFUnit & Unit,DebugMap & ModuleMap,unsigned Indent)3223*9880d681SAndroid Build Coastguard Worker bool DwarfLinker::registerModuleReference(
3224*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &CUDie, const DWARFUnit &Unit,
3225*9880d681SAndroid Build Coastguard Worker DebugMap &ModuleMap, unsigned Indent) {
3226*9880d681SAndroid Build Coastguard Worker std::string PCMfile =
3227*9880d681SAndroid Build Coastguard Worker CUDie.getAttributeValueAsString(&Unit, dwarf::DW_AT_dwo_name, "");
3228*9880d681SAndroid Build Coastguard Worker if (PCMfile.empty())
3229*9880d681SAndroid Build Coastguard Worker PCMfile =
3230*9880d681SAndroid Build Coastguard Worker CUDie.getAttributeValueAsString(&Unit, dwarf::DW_AT_GNU_dwo_name, "");
3231*9880d681SAndroid Build Coastguard Worker if (PCMfile.empty())
3232*9880d681SAndroid Build Coastguard Worker return false;
3233*9880d681SAndroid Build Coastguard Worker
3234*9880d681SAndroid Build Coastguard Worker // Clang module DWARF skeleton CUs abuse this for the path to the module.
3235*9880d681SAndroid Build Coastguard Worker std::string PCMpath =
3236*9880d681SAndroid Build Coastguard Worker CUDie.getAttributeValueAsString(&Unit, dwarf::DW_AT_comp_dir, "");
3237*9880d681SAndroid Build Coastguard Worker uint64_t DwoId = getDwoId(CUDie, Unit);
3238*9880d681SAndroid Build Coastguard Worker
3239*9880d681SAndroid Build Coastguard Worker std::string Name =
3240*9880d681SAndroid Build Coastguard Worker CUDie.getAttributeValueAsString(&Unit, dwarf::DW_AT_name, "");
3241*9880d681SAndroid Build Coastguard Worker if (Name.empty()) {
3242*9880d681SAndroid Build Coastguard Worker reportWarning("Anonymous module skeleton CU for " + PCMfile);
3243*9880d681SAndroid Build Coastguard Worker return true;
3244*9880d681SAndroid Build Coastguard Worker }
3245*9880d681SAndroid Build Coastguard Worker
3246*9880d681SAndroid Build Coastguard Worker if (Options.Verbose) {
3247*9880d681SAndroid Build Coastguard Worker outs().indent(Indent);
3248*9880d681SAndroid Build Coastguard Worker outs() << "Found clang module reference " << PCMfile;
3249*9880d681SAndroid Build Coastguard Worker }
3250*9880d681SAndroid Build Coastguard Worker
3251*9880d681SAndroid Build Coastguard Worker auto Cached = ClangModules.find(PCMfile);
3252*9880d681SAndroid Build Coastguard Worker if (Cached != ClangModules.end()) {
3253*9880d681SAndroid Build Coastguard Worker // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
3254*9880d681SAndroid Build Coastguard Worker // fixed in clang, only warn about DWO_id mismatches in verbose mode.
3255*9880d681SAndroid Build Coastguard Worker // ASTFileSignatures will change randomly when a module is rebuilt.
3256*9880d681SAndroid Build Coastguard Worker if (Options.Verbose && (Cached->second != DwoId))
3257*9880d681SAndroid Build Coastguard Worker reportWarning(Twine("hash mismatch: this object file was built against a "
3258*9880d681SAndroid Build Coastguard Worker "different version of the module ") + PCMfile);
3259*9880d681SAndroid Build Coastguard Worker if (Options.Verbose)
3260*9880d681SAndroid Build Coastguard Worker outs() << " [cached].\n";
3261*9880d681SAndroid Build Coastguard Worker return true;
3262*9880d681SAndroid Build Coastguard Worker }
3263*9880d681SAndroid Build Coastguard Worker if (Options.Verbose)
3264*9880d681SAndroid Build Coastguard Worker outs() << " ...\n";
3265*9880d681SAndroid Build Coastguard Worker
3266*9880d681SAndroid Build Coastguard Worker // Cyclic dependencies are disallowed by Clang, but we still
3267*9880d681SAndroid Build Coastguard Worker // shouldn't run into an infinite loop, so mark it as processed now.
3268*9880d681SAndroid Build Coastguard Worker ClangModules.insert({PCMfile, DwoId});
3269*9880d681SAndroid Build Coastguard Worker loadClangModule(PCMfile, PCMpath, Name, DwoId, ModuleMap, Indent + 2);
3270*9880d681SAndroid Build Coastguard Worker return true;
3271*9880d681SAndroid Build Coastguard Worker }
3272*9880d681SAndroid Build Coastguard Worker
3273*9880d681SAndroid Build Coastguard Worker ErrorOr<const object::ObjectFile &>
loadObject(BinaryHolder & BinaryHolder,DebugMapObject & Obj,const DebugMap & Map)3274*9880d681SAndroid Build Coastguard Worker DwarfLinker::loadObject(BinaryHolder &BinaryHolder, DebugMapObject &Obj,
3275*9880d681SAndroid Build Coastguard Worker const DebugMap &Map) {
3276*9880d681SAndroid Build Coastguard Worker auto ErrOrObjs =
3277*9880d681SAndroid Build Coastguard Worker BinaryHolder.GetObjectFiles(Obj.getObjectFilename(), Obj.getTimestamp());
3278*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = ErrOrObjs.getError()) {
3279*9880d681SAndroid Build Coastguard Worker reportWarning(Twine(Obj.getObjectFilename()) + ": " + EC.message());
3280*9880d681SAndroid Build Coastguard Worker return EC;
3281*9880d681SAndroid Build Coastguard Worker }
3282*9880d681SAndroid Build Coastguard Worker auto ErrOrObj = BinaryHolder.Get(Map.getTriple());
3283*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = ErrOrObj.getError())
3284*9880d681SAndroid Build Coastguard Worker reportWarning(Twine(Obj.getObjectFilename()) + ": " + EC.message());
3285*9880d681SAndroid Build Coastguard Worker return ErrOrObj;
3286*9880d681SAndroid Build Coastguard Worker }
3287*9880d681SAndroid Build Coastguard Worker
loadClangModule(StringRef Filename,StringRef ModulePath,StringRef ModuleName,uint64_t DwoId,DebugMap & ModuleMap,unsigned Indent)3288*9880d681SAndroid Build Coastguard Worker void DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
3289*9880d681SAndroid Build Coastguard Worker StringRef ModuleName, uint64_t DwoId,
3290*9880d681SAndroid Build Coastguard Worker DebugMap &ModuleMap, unsigned Indent) {
3291*9880d681SAndroid Build Coastguard Worker SmallString<80> Path(Options.PrependPath);
3292*9880d681SAndroid Build Coastguard Worker if (sys::path::is_relative(Filename))
3293*9880d681SAndroid Build Coastguard Worker sys::path::append(Path, ModulePath, Filename);
3294*9880d681SAndroid Build Coastguard Worker else
3295*9880d681SAndroid Build Coastguard Worker sys::path::append(Path, Filename);
3296*9880d681SAndroid Build Coastguard Worker BinaryHolder ObjHolder(Options.Verbose);
3297*9880d681SAndroid Build Coastguard Worker auto &Obj =
3298*9880d681SAndroid Build Coastguard Worker ModuleMap.addDebugMapObject(Path, sys::TimeValue::PosixZeroTime());
3299*9880d681SAndroid Build Coastguard Worker auto ErrOrObj = loadObject(ObjHolder, Obj, ModuleMap);
3300*9880d681SAndroid Build Coastguard Worker if (!ErrOrObj) {
3301*9880d681SAndroid Build Coastguard Worker // Try and emit more helpful warnings by applying some heuristics.
3302*9880d681SAndroid Build Coastguard Worker StringRef ObjFile = CurrentDebugObject->getObjectFilename();
3303*9880d681SAndroid Build Coastguard Worker bool isClangModule = sys::path::extension(Filename).equals(".pcm");
3304*9880d681SAndroid Build Coastguard Worker bool isArchive = ObjFile.endswith(")");
3305*9880d681SAndroid Build Coastguard Worker if (isClangModule) {
3306*9880d681SAndroid Build Coastguard Worker StringRef ModuleCacheDir = sys::path::parent_path(Path);
3307*9880d681SAndroid Build Coastguard Worker if (sys::fs::exists(ModuleCacheDir)) {
3308*9880d681SAndroid Build Coastguard Worker // If the module's parent directory exists, we assume that the module
3309*9880d681SAndroid Build Coastguard Worker // cache has expired and was pruned by clang. A more adventurous
3310*9880d681SAndroid Build Coastguard Worker // dsymutil would invoke clang to rebuild the module now.
3311*9880d681SAndroid Build Coastguard Worker if (!ModuleCacheHintDisplayed) {
3312*9880d681SAndroid Build Coastguard Worker errs() << "note: The clang module cache may have expired since this "
3313*9880d681SAndroid Build Coastguard Worker "object file was built. Rebuilding the object file will "
3314*9880d681SAndroid Build Coastguard Worker "rebuild the module cache.\n";
3315*9880d681SAndroid Build Coastguard Worker ModuleCacheHintDisplayed = true;
3316*9880d681SAndroid Build Coastguard Worker }
3317*9880d681SAndroid Build Coastguard Worker } else if (isArchive) {
3318*9880d681SAndroid Build Coastguard Worker // If the module cache directory doesn't exist at all and the object
3319*9880d681SAndroid Build Coastguard Worker // file is inside a static library, we assume that the static library
3320*9880d681SAndroid Build Coastguard Worker // was built on a different machine. We don't want to discourage module
3321*9880d681SAndroid Build Coastguard Worker // debugging for convenience libraries within a project though.
3322*9880d681SAndroid Build Coastguard Worker if (!ArchiveHintDisplayed) {
3323*9880d681SAndroid Build Coastguard Worker errs() << "note: Linking a static library that was built with "
3324*9880d681SAndroid Build Coastguard Worker "-gmodules, but the module cache was not found. "
3325*9880d681SAndroid Build Coastguard Worker "Redistributable static libraries should never be built "
3326*9880d681SAndroid Build Coastguard Worker "with module debugging enabled. The debug experience will "
3327*9880d681SAndroid Build Coastguard Worker "be degraded due to incomplete debug information.\n";
3328*9880d681SAndroid Build Coastguard Worker ArchiveHintDisplayed = true;
3329*9880d681SAndroid Build Coastguard Worker }
3330*9880d681SAndroid Build Coastguard Worker }
3331*9880d681SAndroid Build Coastguard Worker }
3332*9880d681SAndroid Build Coastguard Worker return;
3333*9880d681SAndroid Build Coastguard Worker }
3334*9880d681SAndroid Build Coastguard Worker
3335*9880d681SAndroid Build Coastguard Worker std::unique_ptr<CompileUnit> Unit;
3336*9880d681SAndroid Build Coastguard Worker
3337*9880d681SAndroid Build Coastguard Worker // Setup access to the debug info.
3338*9880d681SAndroid Build Coastguard Worker DWARFContextInMemory DwarfContext(*ErrOrObj);
3339*9880d681SAndroid Build Coastguard Worker RelocationManager RelocMgr(*this);
3340*9880d681SAndroid Build Coastguard Worker for (const auto &CU : DwarfContext.compile_units()) {
3341*9880d681SAndroid Build Coastguard Worker auto *CUDie = CU->getUnitDIE(false);
3342*9880d681SAndroid Build Coastguard Worker // Recursively get all modules imported by this one.
3343*9880d681SAndroid Build Coastguard Worker if (!registerModuleReference(*CUDie, *CU, ModuleMap, Indent)) {
3344*9880d681SAndroid Build Coastguard Worker if (Unit) {
3345*9880d681SAndroid Build Coastguard Worker errs() << Filename << ": Clang modules are expected to have exactly"
3346*9880d681SAndroid Build Coastguard Worker << " 1 compile unit.\n";
3347*9880d681SAndroid Build Coastguard Worker exitDsymutil(1);
3348*9880d681SAndroid Build Coastguard Worker }
3349*9880d681SAndroid Build Coastguard Worker // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
3350*9880d681SAndroid Build Coastguard Worker // fixed in clang, only warn about DWO_id mismatches in verbose mode.
3351*9880d681SAndroid Build Coastguard Worker // ASTFileSignatures will change randomly when a module is rebuilt.
3352*9880d681SAndroid Build Coastguard Worker uint64_t PCMDwoId = getDwoId(*CUDie, *CU);
3353*9880d681SAndroid Build Coastguard Worker if (PCMDwoId != DwoId) {
3354*9880d681SAndroid Build Coastguard Worker if (Options.Verbose)
3355*9880d681SAndroid Build Coastguard Worker reportWarning(
3356*9880d681SAndroid Build Coastguard Worker Twine("hash mismatch: this object file was built against a "
3357*9880d681SAndroid Build Coastguard Worker "different version of the module ") + Filename);
3358*9880d681SAndroid Build Coastguard Worker // Update the cache entry with the DwoId of the module loaded from disk.
3359*9880d681SAndroid Build Coastguard Worker ClangModules[Filename] = PCMDwoId;
3360*9880d681SAndroid Build Coastguard Worker }
3361*9880d681SAndroid Build Coastguard Worker
3362*9880d681SAndroid Build Coastguard Worker // Add this module.
3363*9880d681SAndroid Build Coastguard Worker Unit = llvm::make_unique<CompileUnit>(*CU, UnitID++, !Options.NoODR,
3364*9880d681SAndroid Build Coastguard Worker ModuleName);
3365*9880d681SAndroid Build Coastguard Worker Unit->setHasInterestingContent();
3366*9880d681SAndroid Build Coastguard Worker analyzeContextInfo(CUDie, 0, *Unit, &ODRContexts.getRoot(), StringPool,
3367*9880d681SAndroid Build Coastguard Worker ODRContexts);
3368*9880d681SAndroid Build Coastguard Worker // Keep everything.
3369*9880d681SAndroid Build Coastguard Worker Unit->markEverythingAsKept();
3370*9880d681SAndroid Build Coastguard Worker }
3371*9880d681SAndroid Build Coastguard Worker }
3372*9880d681SAndroid Build Coastguard Worker if (Options.Verbose) {
3373*9880d681SAndroid Build Coastguard Worker outs().indent(Indent);
3374*9880d681SAndroid Build Coastguard Worker outs() << "cloning .debug_info from " << Filename << "\n";
3375*9880d681SAndroid Build Coastguard Worker }
3376*9880d681SAndroid Build Coastguard Worker
3377*9880d681SAndroid Build Coastguard Worker DIECloner(*this, RelocMgr, DIEAlloc, MutableArrayRef<CompileUnit>(*Unit),
3378*9880d681SAndroid Build Coastguard Worker Options)
3379*9880d681SAndroid Build Coastguard Worker .cloneAllCompileUnits(DwarfContext);
3380*9880d681SAndroid Build Coastguard Worker }
3381*9880d681SAndroid Build Coastguard Worker
cloneAllCompileUnits(DWARFContextInMemory & DwarfContext)3382*9880d681SAndroid Build Coastguard Worker void DwarfLinker::DIECloner::cloneAllCompileUnits(
3383*9880d681SAndroid Build Coastguard Worker DWARFContextInMemory &DwarfContext) {
3384*9880d681SAndroid Build Coastguard Worker if (!Linker.Streamer)
3385*9880d681SAndroid Build Coastguard Worker return;
3386*9880d681SAndroid Build Coastguard Worker
3387*9880d681SAndroid Build Coastguard Worker for (auto &CurrentUnit : CompileUnits) {
3388*9880d681SAndroid Build Coastguard Worker const auto *InputDIE = CurrentUnit.getOrigUnit().getUnitDIE();
3389*9880d681SAndroid Build Coastguard Worker CurrentUnit.setStartOffset(Linker.OutputDebugInfoSize);
3390*9880d681SAndroid Build Coastguard Worker DIE *OutputDIE = cloneDIE(*InputDIE, CurrentUnit, 0 /* PC offset */,
3391*9880d681SAndroid Build Coastguard Worker 11 /* Unit Header size */, 0);
3392*9880d681SAndroid Build Coastguard Worker CurrentUnit.setOutputUnitDIE(OutputDIE);
3393*9880d681SAndroid Build Coastguard Worker Linker.OutputDebugInfoSize = CurrentUnit.computeNextUnitOffset();
3394*9880d681SAndroid Build Coastguard Worker if (Linker.Options.NoOutput)
3395*9880d681SAndroid Build Coastguard Worker continue;
3396*9880d681SAndroid Build Coastguard Worker // FIXME: for compatibility with the classic dsymutil, we emit
3397*9880d681SAndroid Build Coastguard Worker // an empty line table for the unit, even if the unit doesn't
3398*9880d681SAndroid Build Coastguard Worker // actually exist in the DIE tree.
3399*9880d681SAndroid Build Coastguard Worker Linker.patchLineTableForUnit(CurrentUnit, DwarfContext);
3400*9880d681SAndroid Build Coastguard Worker if (!OutputDIE)
3401*9880d681SAndroid Build Coastguard Worker continue;
3402*9880d681SAndroid Build Coastguard Worker Linker.patchRangesForUnit(CurrentUnit, DwarfContext);
3403*9880d681SAndroid Build Coastguard Worker Linker.Streamer->emitLocationsForUnit(CurrentUnit, DwarfContext);
3404*9880d681SAndroid Build Coastguard Worker Linker.emitAcceleratorEntriesForUnit(CurrentUnit);
3405*9880d681SAndroid Build Coastguard Worker }
3406*9880d681SAndroid Build Coastguard Worker
3407*9880d681SAndroid Build Coastguard Worker if (Linker.Options.NoOutput)
3408*9880d681SAndroid Build Coastguard Worker return;
3409*9880d681SAndroid Build Coastguard Worker
3410*9880d681SAndroid Build Coastguard Worker // Emit all the compile unit's debug information.
3411*9880d681SAndroid Build Coastguard Worker for (auto &CurrentUnit : CompileUnits) {
3412*9880d681SAndroid Build Coastguard Worker Linker.generateUnitRanges(CurrentUnit);
3413*9880d681SAndroid Build Coastguard Worker CurrentUnit.fixupForwardReferences();
3414*9880d681SAndroid Build Coastguard Worker Linker.Streamer->emitCompileUnitHeader(CurrentUnit);
3415*9880d681SAndroid Build Coastguard Worker if (!CurrentUnit.getOutputUnitDIE())
3416*9880d681SAndroid Build Coastguard Worker continue;
3417*9880d681SAndroid Build Coastguard Worker Linker.Streamer->emitDIE(*CurrentUnit.getOutputUnitDIE());
3418*9880d681SAndroid Build Coastguard Worker }
3419*9880d681SAndroid Build Coastguard Worker }
3420*9880d681SAndroid Build Coastguard Worker
link(const DebugMap & Map)3421*9880d681SAndroid Build Coastguard Worker bool DwarfLinker::link(const DebugMap &Map) {
3422*9880d681SAndroid Build Coastguard Worker
3423*9880d681SAndroid Build Coastguard Worker if (!createStreamer(Map.getTriple(), OutputFilename))
3424*9880d681SAndroid Build Coastguard Worker return false;
3425*9880d681SAndroid Build Coastguard Worker
3426*9880d681SAndroid Build Coastguard Worker // Size of the DIEs (and headers) generated for the linked output.
3427*9880d681SAndroid Build Coastguard Worker OutputDebugInfoSize = 0;
3428*9880d681SAndroid Build Coastguard Worker // A unique ID that identifies each compile unit.
3429*9880d681SAndroid Build Coastguard Worker UnitID = 0;
3430*9880d681SAndroid Build Coastguard Worker DebugMap ModuleMap(Map.getTriple(), Map.getBinaryPath());
3431*9880d681SAndroid Build Coastguard Worker
3432*9880d681SAndroid Build Coastguard Worker for (const auto &Obj : Map.objects()) {
3433*9880d681SAndroid Build Coastguard Worker CurrentDebugObject = Obj.get();
3434*9880d681SAndroid Build Coastguard Worker
3435*9880d681SAndroid Build Coastguard Worker if (Options.Verbose)
3436*9880d681SAndroid Build Coastguard Worker outs() << "DEBUG MAP OBJECT: " << Obj->getObjectFilename() << "\n";
3437*9880d681SAndroid Build Coastguard Worker auto ErrOrObj = loadObject(BinHolder, *Obj, Map);
3438*9880d681SAndroid Build Coastguard Worker if (!ErrOrObj)
3439*9880d681SAndroid Build Coastguard Worker continue;
3440*9880d681SAndroid Build Coastguard Worker
3441*9880d681SAndroid Build Coastguard Worker // Look for relocations that correspond to debug map entries.
3442*9880d681SAndroid Build Coastguard Worker RelocationManager RelocMgr(*this);
3443*9880d681SAndroid Build Coastguard Worker if (!RelocMgr.findValidRelocsInDebugInfo(*ErrOrObj, *Obj)) {
3444*9880d681SAndroid Build Coastguard Worker if (Options.Verbose)
3445*9880d681SAndroid Build Coastguard Worker outs() << "No valid relocations found. Skipping.\n";
3446*9880d681SAndroid Build Coastguard Worker continue;
3447*9880d681SAndroid Build Coastguard Worker }
3448*9880d681SAndroid Build Coastguard Worker
3449*9880d681SAndroid Build Coastguard Worker // Setup access to the debug info.
3450*9880d681SAndroid Build Coastguard Worker DWARFContextInMemory DwarfContext(*ErrOrObj);
3451*9880d681SAndroid Build Coastguard Worker startDebugObject(DwarfContext, *Obj);
3452*9880d681SAndroid Build Coastguard Worker
3453*9880d681SAndroid Build Coastguard Worker // In a first phase, just read in the debug info and load all clang modules.
3454*9880d681SAndroid Build Coastguard Worker for (const auto &CU : DwarfContext.compile_units()) {
3455*9880d681SAndroid Build Coastguard Worker auto *CUDie = CU->getUnitDIE(false);
3456*9880d681SAndroid Build Coastguard Worker if (Options.Verbose) {
3457*9880d681SAndroid Build Coastguard Worker outs() << "Input compilation unit:";
3458*9880d681SAndroid Build Coastguard Worker CUDie->dump(outs(), CU.get(), 0);
3459*9880d681SAndroid Build Coastguard Worker }
3460*9880d681SAndroid Build Coastguard Worker
3461*9880d681SAndroid Build Coastguard Worker if (!registerModuleReference(*CUDie, *CU, ModuleMap))
3462*9880d681SAndroid Build Coastguard Worker Units.emplace_back(*CU, UnitID++, !Options.NoODR, "");
3463*9880d681SAndroid Build Coastguard Worker }
3464*9880d681SAndroid Build Coastguard Worker
3465*9880d681SAndroid Build Coastguard Worker // Now build the DIE parent links that we will use during the next phase.
3466*9880d681SAndroid Build Coastguard Worker for (auto &CurrentUnit : Units)
3467*9880d681SAndroid Build Coastguard Worker analyzeContextInfo(CurrentUnit.getOrigUnit().getUnitDIE(), 0, CurrentUnit,
3468*9880d681SAndroid Build Coastguard Worker &ODRContexts.getRoot(), StringPool, ODRContexts);
3469*9880d681SAndroid Build Coastguard Worker
3470*9880d681SAndroid Build Coastguard Worker // Then mark all the DIEs that need to be present in the linked
3471*9880d681SAndroid Build Coastguard Worker // output and collect some information about them. Note that this
3472*9880d681SAndroid Build Coastguard Worker // loop can not be merged with the previous one becaue cross-cu
3473*9880d681SAndroid Build Coastguard Worker // references require the ParentIdx to be setup for every CU in
3474*9880d681SAndroid Build Coastguard Worker // the object file before calling this.
3475*9880d681SAndroid Build Coastguard Worker for (auto &CurrentUnit : Units)
3476*9880d681SAndroid Build Coastguard Worker lookForDIEsToKeep(RelocMgr, *CurrentUnit.getOrigUnit().getUnitDIE(), *Obj,
3477*9880d681SAndroid Build Coastguard Worker CurrentUnit, 0);
3478*9880d681SAndroid Build Coastguard Worker
3479*9880d681SAndroid Build Coastguard Worker // The calls to applyValidRelocs inside cloneDIE will walk the
3480*9880d681SAndroid Build Coastguard Worker // reloc array again (in the same way findValidRelocsInDebugInfo()
3481*9880d681SAndroid Build Coastguard Worker // did). We need to reset the NextValidReloc index to the beginning.
3482*9880d681SAndroid Build Coastguard Worker RelocMgr.resetValidRelocs();
3483*9880d681SAndroid Build Coastguard Worker if (RelocMgr.hasValidRelocs())
3484*9880d681SAndroid Build Coastguard Worker DIECloner(*this, RelocMgr, DIEAlloc, Units, Options)
3485*9880d681SAndroid Build Coastguard Worker .cloneAllCompileUnits(DwarfContext);
3486*9880d681SAndroid Build Coastguard Worker if (!Options.NoOutput && !Units.empty())
3487*9880d681SAndroid Build Coastguard Worker patchFrameInfoForObject(*Obj, DwarfContext,
3488*9880d681SAndroid Build Coastguard Worker Units[0].getOrigUnit().getAddressByteSize());
3489*9880d681SAndroid Build Coastguard Worker
3490*9880d681SAndroid Build Coastguard Worker // Clean-up before starting working on the next object.
3491*9880d681SAndroid Build Coastguard Worker endDebugObject();
3492*9880d681SAndroid Build Coastguard Worker }
3493*9880d681SAndroid Build Coastguard Worker
3494*9880d681SAndroid Build Coastguard Worker // Emit everything that's global.
3495*9880d681SAndroid Build Coastguard Worker if (!Options.NoOutput) {
3496*9880d681SAndroid Build Coastguard Worker Streamer->emitAbbrevs(Abbreviations);
3497*9880d681SAndroid Build Coastguard Worker Streamer->emitStrings(StringPool);
3498*9880d681SAndroid Build Coastguard Worker }
3499*9880d681SAndroid Build Coastguard Worker
3500*9880d681SAndroid Build Coastguard Worker return Options.NoOutput ? true : Streamer->finish(Map);
3501*9880d681SAndroid Build Coastguard Worker }
3502*9880d681SAndroid Build Coastguard Worker }
3503*9880d681SAndroid Build Coastguard Worker
3504*9880d681SAndroid Build Coastguard Worker /// \brief Get the offset of string \p S in the string table. This
3505*9880d681SAndroid Build Coastguard Worker /// can insert a new element or return the offset of a preexisitng
3506*9880d681SAndroid Build Coastguard Worker /// one.
getStringOffset(StringRef S)3507*9880d681SAndroid Build Coastguard Worker uint32_t NonRelocatableStringpool::getStringOffset(StringRef S) {
3508*9880d681SAndroid Build Coastguard Worker if (S.empty() && !Strings.empty())
3509*9880d681SAndroid Build Coastguard Worker return 0;
3510*9880d681SAndroid Build Coastguard Worker
3511*9880d681SAndroid Build Coastguard Worker std::pair<uint32_t, StringMapEntryBase *> Entry(0, nullptr);
3512*9880d681SAndroid Build Coastguard Worker MapTy::iterator It;
3513*9880d681SAndroid Build Coastguard Worker bool Inserted;
3514*9880d681SAndroid Build Coastguard Worker
3515*9880d681SAndroid Build Coastguard Worker // A non-empty string can't be at offset 0, so if we have an entry
3516*9880d681SAndroid Build Coastguard Worker // with a 0 offset, it must be a previously interned string.
3517*9880d681SAndroid Build Coastguard Worker std::tie(It, Inserted) = Strings.insert(std::make_pair(S, Entry));
3518*9880d681SAndroid Build Coastguard Worker if (Inserted || It->getValue().first == 0) {
3519*9880d681SAndroid Build Coastguard Worker // Set offset and chain at the end of the entries list.
3520*9880d681SAndroid Build Coastguard Worker It->getValue().first = CurrentEndOffset;
3521*9880d681SAndroid Build Coastguard Worker CurrentEndOffset += S.size() + 1; // +1 for the '\0'.
3522*9880d681SAndroid Build Coastguard Worker Last->getValue().second = &*It;
3523*9880d681SAndroid Build Coastguard Worker Last = &*It;
3524*9880d681SAndroid Build Coastguard Worker }
3525*9880d681SAndroid Build Coastguard Worker return It->getValue().first;
3526*9880d681SAndroid Build Coastguard Worker }
3527*9880d681SAndroid Build Coastguard Worker
3528*9880d681SAndroid Build Coastguard Worker /// \brief Put \p S into the StringMap so that it gets permanent
3529*9880d681SAndroid Build Coastguard Worker /// storage, but do not actually link it in the chain of elements
3530*9880d681SAndroid Build Coastguard Worker /// that go into the output section. A latter call to
3531*9880d681SAndroid Build Coastguard Worker /// getStringOffset() with the same string will chain it though.
internString(StringRef S)3532*9880d681SAndroid Build Coastguard Worker StringRef NonRelocatableStringpool::internString(StringRef S) {
3533*9880d681SAndroid Build Coastguard Worker std::pair<uint32_t, StringMapEntryBase *> Entry(0, nullptr);
3534*9880d681SAndroid Build Coastguard Worker auto InsertResult = Strings.insert(std::make_pair(S, Entry));
3535*9880d681SAndroid Build Coastguard Worker return InsertResult.first->getKey();
3536*9880d681SAndroid Build Coastguard Worker }
3537*9880d681SAndroid Build Coastguard Worker
warn(const Twine & Warning,const Twine & Context)3538*9880d681SAndroid Build Coastguard Worker void warn(const Twine &Warning, const Twine &Context) {
3539*9880d681SAndroid Build Coastguard Worker errs() << Twine("while processing ") + Context + ":\n";
3540*9880d681SAndroid Build Coastguard Worker errs() << Twine("warning: ") + Warning + "\n";
3541*9880d681SAndroid Build Coastguard Worker }
3542*9880d681SAndroid Build Coastguard Worker
error(const Twine & Error,const Twine & Context)3543*9880d681SAndroid Build Coastguard Worker bool error(const Twine &Error, const Twine &Context) {
3544*9880d681SAndroid Build Coastguard Worker errs() << Twine("while processing ") + Context + ":\n";
3545*9880d681SAndroid Build Coastguard Worker errs() << Twine("error: ") + Error + "\n";
3546*9880d681SAndroid Build Coastguard Worker return false;
3547*9880d681SAndroid Build Coastguard Worker }
3548*9880d681SAndroid Build Coastguard Worker
linkDwarf(StringRef OutputFilename,const DebugMap & DM,const LinkOptions & Options)3549*9880d681SAndroid Build Coastguard Worker bool linkDwarf(StringRef OutputFilename, const DebugMap &DM,
3550*9880d681SAndroid Build Coastguard Worker const LinkOptions &Options) {
3551*9880d681SAndroid Build Coastguard Worker DwarfLinker Linker(OutputFilename, Options);
3552*9880d681SAndroid Build Coastguard Worker return Linker.link(DM);
3553*9880d681SAndroid Build Coastguard Worker }
3554*9880d681SAndroid Build Coastguard Worker }
3555*9880d681SAndroid Build Coastguard Worker }
3556