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
|
//===- DWARFLinkerTypeUnit.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_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H
#define LLVM_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H
#include "DWARFLinkerUnit.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
namespace llvm {
namespace dwarf_linker {
namespace parallel {
/// Type Unit is used to represent an artificial compilation unit
/// which keeps all type information. This type information is referenced
/// from other compilation units.
class TypeUnit : public DwarfUnit {
public:
TypeUnit(LinkingGlobalData &GlobalData, unsigned ID,
std::optional<uint16_t> Language, dwarf::FormParams Format,
llvm::endianness Endianess);
/// Generates DIE tree based on information from TypesMap.
void createDIETree(BumpPtrAllocator &Allocator);
/// Emits resulting dwarf based on information from DIE tree.
Error finishCloningAndEmit(const Triple &TargetTriple);
/// Returns global type pool.
TypePool &getTypePool() { return Types; }
/// TypeUnitAccelInfo extends AccelInfo structure with type specific fileds.
/// We need these additional fields to decide whether OutDIE should have an
/// accelerator record or not. The TypeEntryBodyPtr can refer to the
/// declaration DIE and definition DIE corresponding to the type entry.
/// Only one of them would be used in final output. So if TypeUnitAccelInfo
/// refers OutDIE which does not match with TypeEntryBodyPtr->getFinalDie()
/// then such record should be skipped.
struct TypeUnitAccelInfo : public AccelInfo {
/// Pointer to the output DIE which owns this accelerator record.
DIE *OutDIE = nullptr;
/// Pointer to the type entry body.
TypeEntryBody *TypeEntryBodyPtr = nullptr;
};
/// Enumerates all accelerator records and call \p Handler for each.
void
forEachAcceleratorRecord(function_ref<void(AccelInfo &)> Handler) override {
AcceleratorRecords.forEach([&](TypeUnitAccelInfo &Info) {
// Check whether current record is for the final DIE.
assert(Info.TypeEntryBodyPtr != nullptr);
if (&Info.TypeEntryBodyPtr->getFinalDie() != Info.OutDIE)
return;
Info.OutOffset = Info.OutDIE->getOffset();
Handler(Info);
});
}
/// Returns index for the specified \p String inside .debug_str_offsets.
uint64_t getDebugStrIndex(const StringEntry *String) override {
std::unique_lock<std::mutex> LockGuard(DebugStringIndexMapMutex);
return DebugStringIndexMap.getValueIndex(String);
}
/// Adds \p Info to the unit's accelerator records.
void saveAcceleratorInfo(const TypeUnitAccelInfo &Info) {
AcceleratorRecords.add(Info);
}
private:
/// Type DIEs are partially created at clonning stage. They are organised
/// as a tree using type entries. This function links DIEs(corresponding
/// to the type entries) into the tree structure.
uint64_t finalizeTypeEntryRec(uint64_t OutOffset, DIE *OutDIE,
TypeEntry *Entry);
/// Prepares DIEs to be linked into the tree.
void prepareDataForTreeCreation();
/// Add specified \p Dir and \p Filename into the line table
/// of this type unit.
uint32_t addFileNameIntoLinetable(StringEntry *Dir, StringEntry *FileName);
std::pair<dwarf::Form, uint8_t> getScalarFormForValue(uint64_t Value) const;
uint8_t getSizeByAttrForm(dwarf::Form Form) const;
struct CmpStringEntryRef {
bool operator()(const StringEntry *LHS, const StringEntry *RHS) const {
return LHS->first() < RHS->first();
}
};
struct CmpDirIDStringEntryRef {
bool operator()(const std::pair<StringEntry *, uint64_t> &LHS,
const std::pair<StringEntry *, uint64_t> &RHS) const {
return LHS.second < RHS.second ||
(!(RHS.second < LHS.second) &&
LHS.first->first() < RHS.first->first());
}
};
/// The DW_AT_language of this unit.
std::optional<uint16_t> Language;
/// This unit line table.
DWARFDebugLine::LineTable LineTable;
/// Data members keeping file names for line table.
using DirectoriesMapTy = std::map<StringEntry *, size_t, CmpStringEntryRef>;
using FilenamesMapTy = std::map<std::pair<StringEntry *, uint64_t>, size_t,
CmpDirIDStringEntryRef>;
DirectoriesMapTy DirectoriesMap;
FilenamesMapTy FileNamesMap;
/// Type DIEs tree.
TypePool Types;
/// List of accelerator entries for this unit.
ArrayList<TypeUnitAccelInfo> AcceleratorRecords;
/// Guard for DebugStringIndexMap.
std::mutex DebugStringIndexMapMutex;
};
} // end of namespace parallel
} // end of namespace dwarf_linker
} // end of namespace llvm
#endif // LLVM_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H
|