mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 16:36:40 +00:00
f589dab5bf
This patch splits off some abstractions used by dsymutil's dwarf linker and moves them into separate header and implementation files. This almost halves the number of LOC in DwarfLinker.cpp and makes it a lot easier to understand what functionality lives where. Differential revision: https://reviews.llvm.org/D48647 llvm-svn: 335749
137 lines
4.5 KiB
C++
137 lines
4.5 KiB
C++
//===- tools/dsymutil/CompileUnit.h - Dwarf compile unit ------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "CompileUnit.h"
|
|
#include "DeclContext.h"
|
|
|
|
namespace llvm {
|
|
namespace dsymutil {
|
|
|
|
/// Check if the DIE at \p Idx is in the scope of a function.
|
|
static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
|
|
while (Idx) {
|
|
if (U.getOrigUnit().getDIEAtIndex(Idx).getTag() == dwarf::DW_TAG_subprogram)
|
|
return true;
|
|
Idx = U.getInfo(Idx).ParentIdx;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CompileUnit::markEverythingAsKept() {
|
|
unsigned Idx = 0;
|
|
|
|
setHasInterestingContent();
|
|
|
|
for (auto &I : Info) {
|
|
// Mark everything that wasn't explicit marked for pruning.
|
|
I.Keep = !I.Prune;
|
|
auto DIE = OrigUnit.getDIEAtIndex(Idx++);
|
|
|
|
// Try to guess which DIEs must go to the accelerator tables. We do that
|
|
// just for variables, because functions will be handled depending on
|
|
// whether they carry a DW_AT_low_pc attribute or not.
|
|
if (DIE.getTag() != dwarf::DW_TAG_variable &&
|
|
DIE.getTag() != dwarf::DW_TAG_constant)
|
|
continue;
|
|
|
|
Optional<DWARFFormValue> Value;
|
|
if (!(Value = DIE.find(dwarf::DW_AT_location))) {
|
|
if ((Value = DIE.find(dwarf::DW_AT_const_value)) &&
|
|
!inFunctionScope(*this, I.ParentIdx))
|
|
I.InDebugMap = true;
|
|
continue;
|
|
}
|
|
if (auto Block = Value->getAsBlock()) {
|
|
if (Block->size() > OrigUnit.getAddressByteSize() &&
|
|
(*Block)[0] == dwarf::DW_OP_addr)
|
|
I.InDebugMap = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint64_t CompileUnit::computeNextUnitOffset() {
|
|
NextUnitOffset = StartOffset + 11 /* Header size */;
|
|
// The root DIE might be null, meaning that the Unit had nothing to
|
|
// contribute to the linked output. In that case, we will emit the
|
|
// unit header without any actual DIE.
|
|
if (NewUnit)
|
|
NextUnitOffset += NewUnit->getUnitDie().getSize();
|
|
return NextUnitOffset;
|
|
}
|
|
|
|
/// Keep track of a forward cross-cu reference from this unit
|
|
/// to \p Die that lives in \p RefUnit.
|
|
void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
|
|
DeclContext *Ctxt, PatchLocation Attr) {
|
|
ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr);
|
|
}
|
|
|
|
void CompileUnit::fixupForwardReferences() {
|
|
for (const auto &Ref : ForwardDIEReferences) {
|
|
DIE *RefDie;
|
|
const CompileUnit *RefUnit;
|
|
PatchLocation Attr;
|
|
DeclContext *Ctxt;
|
|
std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref;
|
|
if (Ctxt && Ctxt->getCanonicalDIEOffset())
|
|
Attr.set(Ctxt->getCanonicalDIEOffset());
|
|
else
|
|
Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());
|
|
}
|
|
}
|
|
|
|
void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
|
|
Labels.insert({LabelLowPc, PcOffset});
|
|
}
|
|
|
|
void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
|
|
int64_t PcOffset) {
|
|
Ranges.insert(FuncLowPc, FuncHighPc, PcOffset);
|
|
this->LowPc = std::min(LowPc, FuncLowPc + PcOffset);
|
|
this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
|
|
}
|
|
|
|
void CompileUnit::noteRangeAttribute(const DIE &Die, PatchLocation Attr) {
|
|
if (Die.getTag() != dwarf::DW_TAG_compile_unit)
|
|
RangeAttributes.push_back(Attr);
|
|
else
|
|
UnitRangeAttribute = Attr;
|
|
}
|
|
|
|
void CompileUnit::noteLocationAttribute(PatchLocation Attr, int64_t PcOffset) {
|
|
LocationAttributes.emplace_back(Attr, PcOffset);
|
|
}
|
|
|
|
void CompileUnit::addNamespaceAccelerator(const DIE *Die,
|
|
DwarfStringPoolEntryRef Name) {
|
|
Namespaces.emplace_back(Name, Die);
|
|
}
|
|
|
|
void CompileUnit::addObjCAccelerator(const DIE *Die,
|
|
DwarfStringPoolEntryRef Name,
|
|
bool SkipPubSection) {
|
|
ObjC.emplace_back(Name, Die, SkipPubSection);
|
|
}
|
|
|
|
void CompileUnit::addNameAccelerator(const DIE *Die,
|
|
DwarfStringPoolEntryRef Name,
|
|
bool SkipPubSection) {
|
|
Pubnames.emplace_back(Name, Die, SkipPubSection);
|
|
}
|
|
|
|
void CompileUnit::addTypeAccelerator(const DIE *Die,
|
|
DwarfStringPoolEntryRef Name,
|
|
bool ObjcClassImplementation,
|
|
uint32_t QualifiedNameHash) {
|
|
Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation);
|
|
}
|
|
|
|
} // namespace dsymutil
|
|
} // namespace llvm
|