1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
//===- DWARFLinkerUnit.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_DWARFLINKERUNIT_H
#define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERUNIT_H
#include "DWARFLinkerGlobalData.h"
#include "OutputSections.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/DWARFLinker/IndexedValuesMap.h"
#include "llvm/DWARFLinker/Parallel/DWARFLinker.h"
#include "llvm/DWARFLinker/StringPool.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/LEB128.h"
namespace llvm {
namespace dwarf_linker {
namespace parallel {
class DwarfUnit;
using MacroOffset2UnitMapTy = DenseMap<uint64_t, DwarfUnit *>;
/// Base class for all Dwarf units(Compile unit/Type table unit).
class DwarfUnit : public OutputSections {
public:
virtual ~DwarfUnit() {}
DwarfUnit(LinkingGlobalData &GlobalData, unsigned ID,
StringRef ClangModuleName)
: OutputSections(GlobalData), ID(ID), ClangModuleName(ClangModuleName),
OutUnitDIE(nullptr) {}
/// Unique id of the unit.
unsigned getUniqueID() const { return ID; }
/// Returns size of this(newly generated) compile unit.
uint64_t getUnitSize() const { return UnitSize; }
/// Returns this unit name.
StringRef getUnitName() const { return UnitName; }
/// Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef.
StringRef getSysRoot() { return SysRoot; }
/// Return true if this compile unit is from Clang module.
bool isClangModule() const { return !ClangModuleName.empty(); }
/// Return Clang module name;
const std::string &getClangModuleName() const { return ClangModuleName; }
/// Return global data.
LinkingGlobalData &getGlobalData() { return GlobalData; }
/// Returns true if unit is inter-connected(it references/referenced by other
/// unit).
bool isInterconnectedCU() const { return IsInterconnectedCU; }
/// Mark this unit as inter-connected(it references/referenced by other unit).
void setInterconnectedCU() { IsInterconnectedCU = true; }
/// Adds \p Abbrev into unit`s abbreviation table.
void assignAbbrev(DIEAbbrev &Abbrev);
/// Returns abbreviations for this compile unit.
const std::vector<std::unique_ptr<DIEAbbrev>> &getAbbreviations() const {
return Abbreviations;
}
/// Returns output unit DIE.
DIE *getOutUnitDIE() { return OutUnitDIE; }
/// Set output unit DIE.
void setOutUnitDIE(DIE *UnitDie) {
OutUnitDIE = UnitDie;
if (OutUnitDIE != nullptr)
UnitSize = getDebugInfoHeaderSize() + OutUnitDIE->getSize();
}
/// \defgroup Methods used to emit unit's debug info:
///
/// @{
/// Emit unit's abbreviations.
Error emitAbbreviations();
/// Emit .debug_info section for unit DIEs.
Error emitDebugInfo(const Triple &TargetTriple);
/// Emit .debug_line section.
Error emitDebugLine(const Triple &TargetTriple,
const DWARFDebugLine::LineTable &OutLineTable);
/// Emit the .debug_str_offsets section for current unit.
Error emitDebugStringOffsetSection();
/// @}
/// \defgroup Methods used for reporting warnings and errors:
///
/// @{
void warn(const Twine &Warning) { GlobalData.warn(Warning, getUnitName()); }
void error(const Twine &Err) { GlobalData.warn(Err, getUnitName()); }
/// @}
/// \defgroup Methods and data members used for building accelerator tables:
///
/// @{
enum class AccelType : uint8_t { None, Name, Namespace, ObjC, Type };
/// This structure keeps fields which would be used for creating accelerator
/// table.
struct AccelInfo {
AccelInfo() {
AvoidForPubSections = false;
ObjcClassImplementation = false;
}
/// Name of the entry.
StringEntry *String = nullptr;
/// Output offset of the DIE this entry describes.
uint64_t OutOffset;
/// Hash of the fully qualified name.
uint32_t QualifiedNameHash = 0;
/// Tag of the DIE this entry describes.
dwarf::Tag Tag = dwarf::DW_TAG_null;
/// Type of this accelerator record.
AccelType Type = AccelType::None;
/// Avoid emitting this entry for pub sections.
bool AvoidForPubSections : 1;
/// Is this an ObjC class implementation?
bool ObjcClassImplementation : 1;
};
/// Emit .debug_pubnames and .debug_pubtypes for \p Unit.
void emitPubAccelerators();
/// Enumerates accelerator data.
virtual void
forEachAcceleratorRecord(function_ref<void(AccelInfo &)> Handler) = 0;
/// @}
/// Returns index(inside .debug_str_offsets) of specified string.
virtual uint64_t getDebugStrIndex(const StringEntry *String) {
return DebugStringIndexMap.getValueIndex(String);
}
protected:
/// Emit single abbreviation entry.
void emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev,
SectionDescriptor &AbbrevSection);
/// Emit single pubnames/pubtypes accelerator entry.
std::optional<uint64_t>
emitPubAcceleratorEntry(SectionDescriptor &OutSection, const AccelInfo &Info,
std::optional<uint64_t> LengthOffset);
/// Unique ID for the unit.
unsigned ID = 0;
/// The name of this unit.
std::string UnitName;
/// The DW_AT_LLVM_sysroot of this unit.
std::string SysRoot;
/// If this is a Clang module, this holds the module's name.
std::string ClangModuleName;
uint64_t UnitSize = 0;
/// true if current unit references_to/is_referenced by other unit.
std::atomic<bool> IsInterconnectedCU = {false};
/// FoldingSet that uniques the abbreviations.
FoldingSet<DIEAbbrev> AbbreviationsSet;
/// Storage for the unique Abbreviations.
std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
/// Output unit DIE.
DIE *OutUnitDIE = nullptr;
/// Cache for file names for this unit.
using FileNamesCache =
DenseMap<uint64_t, std::pair<std::string, std::string>>;
FileNamesCache FileNames;
/// Maps a string into the index inside .debug_str_offsets section.
IndexedValuesMap<const StringEntry *> DebugStringIndexMap;
};
inline bool isODRLanguage(uint16_t Language) {
switch (Language) {
case dwarf::DW_LANG_C_plus_plus:
case dwarf::DW_LANG_C_plus_plus_03:
case dwarf::DW_LANG_C_plus_plus_11:
case dwarf::DW_LANG_C_plus_plus_14:
case dwarf::DW_LANG_ObjC_plus_plus:
return true;
default:
return false;
};
return false;
}
} // end of namespace parallel
} // end of namespace dwarf_linker
} // end of namespace llvm
#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERUNIT_H
|