123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- //===- DWARFLinkerCompileUnit.cpp -----------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
- #include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
- namespace llvm {
- /// 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;
- }
- uint16_t CompileUnit::getLanguage() {
- if (!Language) {
- DWARFDie CU = getOrigUnit().getUnitDIE();
- Language = dwarf::toUnsigned(CU.find(dwarf::DW_AT_language), 0);
- }
- return Language;
- }
- StringRef CompileUnit::getSysRoot() {
- if (SysRoot.empty()) {
- DWARFDie CU = getOrigUnit().getUnitDIE();
- SysRoot = dwarf::toStringRef(CU.find(dwarf::DW_AT_LLVM_sysroot)).str();
- }
- return SysRoot;
- }
- void CompileUnit::markEverythingAsKept() {
- unsigned Idx = 0;
- 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(uint16_t DwarfVersion) {
- NextUnitOffset = StartOffset;
- if (NewUnit) {
- NextUnitOffset += (DwarfVersion >= 5) ? 12 : 11; // Header size
- 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) {
- // Don't add empty ranges to the interval map. They are a problem because
- // the interval map expects half open intervals. This is safe because they
- // are empty anyway.
- if (FuncHighPc != FuncLowPc)
- 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 llvm
|