blob: 6a6bd08570d7da2ab10ac51f74ee8cf4cd67f9d2 [file] [log] [blame]
//===- DIEAttributeCloner.h -------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H
#define LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H
#include "ArrayList.h"
#include "DIEGenerator.h"
#include "DWARFLinkerCompileUnit.h"
#include "DWARFLinkerGlobalData.h"
#include "DWARFLinkerTypeUnit.h"
namespace llvm {
namespace dwarf_linker {
namespace parallel {
/// Information gathered and exchanged between the various
/// clone*Attr helpers about the attributes of a particular DIE.
struct AttributesInfo {
/// Short Name.
StringEntry *Name = nullptr;
/// Mangled Name.
StringEntry *MangledName = nullptr;
/// Does the DIE have an address pointing to live code section?
bool HasLiveAddress = false;
/// Is this DIE only a declaration?
bool IsDeclaration = false;
/// Does the DIE have a ranges attribute?
bool HasRanges = false;
/// Does the DIE have a string offset attribute?
bool HasStringOffsetBaseAttr = false;
};
/// This class creates clones of input DIE attributes.
/// It enumerates attributes of input DIE, creates clone for each
/// attribute, adds cloned attribute to the output DIE.
class DIEAttributeCloner {
public:
DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit, CompileUnit *OutUnit,
const DWARFDebugInfoEntry *InputDieEntry,
DIEGenerator &Generator,
std::optional<int64_t> FuncAddressAdjustment,
std::optional<int64_t> VarAddressAdjustment,
bool HasLocationExpressionAddress)
: DIEAttributeCloner(OutDIE, InUnit,
CompileUnit::OutputUnitVariantPtr(OutUnit),
InputDieEntry, Generator, FuncAddressAdjustment,
VarAddressAdjustment, HasLocationExpressionAddress) {
}
DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit, TypeUnit *OutUnit,
const DWARFDebugInfoEntry *InputDieEntry,
DIEGenerator &Generator,
std::optional<int64_t> FuncAddressAdjustment,
std::optional<int64_t> VarAddressAdjustment,
bool HasLocationExpressionAddress)
: DIEAttributeCloner(OutDIE, InUnit,
CompileUnit::OutputUnitVariantPtr(OutUnit),
InputDieEntry, Generator, FuncAddressAdjustment,
VarAddressAdjustment, HasLocationExpressionAddress) {
}
/// Clone attributes of input DIE.
void clone();
/// Create abbreviations for the output DIE after all attributes are cloned.
unsigned finalizeAbbreviations(bool HasChildrenToClone);
/// Cannot be used concurrently.
AttributesInfo AttrInfo;
unsigned getOutOffset() { return AttrOutOffset; }
protected:
DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit,
CompileUnit::OutputUnitVariantPtr OutUnit,
const DWARFDebugInfoEntry *InputDieEntry,
DIEGenerator &Generator,
std::optional<int64_t> FuncAddressAdjustment,
std::optional<int64_t> VarAddressAdjustment,
bool HasLocationExpressionAddress)
: OutDIE(OutDIE), InUnit(InUnit), OutUnit(OutUnit),
DebugInfoOutputSection(
OutUnit->getSectionDescriptor(DebugSectionKind::DebugInfo)),
InputDieEntry(InputDieEntry), Generator(Generator),
FuncAddressAdjustment(FuncAddressAdjustment),
VarAddressAdjustment(VarAddressAdjustment),
HasLocationExpressionAddress(HasLocationExpressionAddress) {
InputDIEIdx = InUnit.getDIEIndex(InputDieEntry);
// Use DW_FORM_strp form for string attributes for DWARF version less than 5
// or if output unit is type unit and we need to produce deterministic
// result. (We can not generate deterministic results for debug_str_offsets
// section when attributes are cloned parallelly).
Use_DW_FORM_strp =
(InUnit.getVersion() < 5) ||
(OutUnit.isTypeUnit() &&
((InUnit.getGlobalData().getOptions().Threads != 1) &&
!InUnit.getGlobalData().getOptions().AllowNonDeterministicOutput));
}
/// Clone string attribute.
size_t
cloneStringAttr(const DWARFFormValue &Val,
const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);
/// Clone attribute referencing another DIE.
size_t
cloneDieRefAttr(const DWARFFormValue &Val,
const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);
/// Clone scalar attribute.
size_t
cloneScalarAttr(const DWARFFormValue &Val,
const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);
/// Clone block or exprloc attribute.
size_t
cloneBlockAttr(const DWARFFormValue &Val,
const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);
/// Clone address attribute.
size_t
cloneAddressAttr(const DWARFFormValue &Val,
const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);
/// Returns true if attribute should be skipped.
bool
shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec);
/// Output DIE.
DIE *OutDIE = nullptr;
/// Input compilation unit.
CompileUnit &InUnit;
/// Output unit(either "plain" compilation unit, either artificial type unit).
CompileUnit::OutputUnitVariantPtr OutUnit;
/// .debug_info section descriptor.
SectionDescriptor &DebugInfoOutputSection;
/// Input DIE entry.
const DWARFDebugInfoEntry *InputDieEntry = nullptr;
/// Input DIE index.
uint32_t InputDIEIdx = 0;
/// Output DIE generator.
DIEGenerator &Generator;
/// Relocation adjustment for the function address ranges.
std::optional<int64_t> FuncAddressAdjustment;
/// Relocation adjustment for the variable locations.
std::optional<int64_t> VarAddressAdjustment;
/// Indicates whether InputDieEntry has an location attribute
/// containg address expression.
bool HasLocationExpressionAddress = false;
/// Output offset after all attributes.
unsigned AttrOutOffset = 0;
/// Patches for the cloned attributes.
OffsetsPtrVector PatchesOffsets;
/// This flag forces using DW_FORM_strp for string attributes.
bool Use_DW_FORM_strp = false;
};
} // end of namespace parallel
} // end of namespace dwarf_linker
} // end of namespace llvm
#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H