Path: blob/main/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DIEGenerator.h
35292 views
//===- DIEGenerator.h -------------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DIEGENERATOR_H9#define LLVM_LIB_DWARFLINKER_PARALLEL_DIEGENERATOR_H1011#include "DWARFLinkerGlobalData.h"12#include "DWARFLinkerUnit.h"13#include "llvm/CodeGen/DIE.h"14#include "llvm/Support/LEB128.h"1516namespace llvm {17namespace dwarf_linker {18namespace parallel {1920/// This class is a helper to create output DIE tree.21class DIEGenerator {22public:23DIEGenerator(BumpPtrAllocator &Allocator, DwarfUnit &CU)24: Allocator(Allocator), CU(CU) {}2526DIEGenerator(DIE *OutputDIE, BumpPtrAllocator &Allocator, DwarfUnit &CU)27: Allocator(Allocator), CU(CU), OutputDIE(OutputDIE) {}2829/// Creates a DIE of specified tag \p DieTag and \p OutOffset.30DIE *createDIE(dwarf::Tag DieTag, uint32_t OutOffset) {31OutputDIE = DIE::get(Allocator, DieTag);3233OutputDIE->setOffset(OutOffset);3435return OutputDIE;36}3738DIE *getDIE() { return OutputDIE; }3940/// Adds a specified \p Child to the current DIE.41void addChild(DIE *Child) {42assert(Child != nullptr);43assert(OutputDIE != nullptr);4445OutputDIE->addChild(Child);46}4748/// Adds specified scalar attribute to the current DIE.49std::pair<DIEValue &, size_t> addScalarAttribute(dwarf::Attribute Attr,50dwarf::Form AttrForm,51uint64_t Value) {52return addAttribute(Attr, AttrForm, DIEInteger(Value));53}5455/// Adds specified location attribute to the current DIE.56std::pair<DIEValue &, size_t> addLocationAttribute(dwarf::Attribute Attr,57dwarf::Form AttrForm,58ArrayRef<uint8_t> Bytes) {59DIELoc *Loc = new (Allocator) DIELoc;60for (auto Byte : Bytes)61static_cast<DIEValueList *>(Loc)->addValue(62Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,63DIEInteger(Byte));64Loc->setSize(Bytes.size());6566return addAttribute(Attr, AttrForm, Loc);67}6869/// Adds specified block or exprloc attribute to the current DIE.70std::pair<DIEValue &, size_t> addBlockAttribute(dwarf::Attribute Attr,71dwarf::Form AttrForm,72ArrayRef<uint8_t> Bytes) {73// The expression location data might be updated and exceed the original74// size. Check whether the new data fits into the original form.75assert((AttrForm == dwarf::DW_FORM_block) ||76(AttrForm == dwarf::DW_FORM_exprloc) ||77(AttrForm == dwarf::DW_FORM_block1 && Bytes.size() <= UINT8_MAX) ||78(AttrForm == dwarf::DW_FORM_block2 && Bytes.size() <= UINT16_MAX) ||79(AttrForm == dwarf::DW_FORM_block4 && Bytes.size() <= UINT32_MAX));8081DIEBlock *Block = new (Allocator) DIEBlock;82for (auto Byte : Bytes)83static_cast<DIEValueList *>(Block)->addValue(84Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,85DIEInteger(Byte));86Block->setSize(Bytes.size());8788return addAttribute(Attr, AttrForm, Block);89}9091/// Adds specified location list attribute to the current DIE.92std::pair<DIEValue &, size_t> addLocListAttribute(dwarf::Attribute Attr,93dwarf::Form AttrForm,94uint64_t Value) {95return addAttribute(Attr, AttrForm, DIELocList(Value));96}9798/// Adds indexed string attribute.99std::pair<DIEValue &, size_t> addIndexedStringAttribute(dwarf::Attribute Attr,100dwarf::Form AttrForm,101uint64_t Idx) {102assert(AttrForm == dwarf::DW_FORM_strx);103return addAttribute(Attr, AttrForm, DIEInteger(Idx));104}105106/// Adds string attribute with dummy offset to the current DIE.107std::pair<DIEValue &, size_t>108addStringPlaceholderAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm) {109assert(AttrForm == dwarf::DW_FORM_strp ||110AttrForm == dwarf::DW_FORM_line_strp);111return addAttribute(Attr, AttrForm, DIEInteger(0xBADDEF));112}113114/// Adds inplace string attribute to the current DIE.115std::pair<DIEValue &, size_t> addInplaceString(dwarf::Attribute Attr,116StringRef String) {117DIEBlock *Block = new (Allocator) DIEBlock;118for (auto Byte : String.bytes())119static_cast<DIEValueList *>(Block)->addValue(120Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,121DIEInteger(Byte));122123static_cast<DIEValueList *>(Block)->addValue(124Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,125DIEInteger(0));126Block->setSize(String.size() + 1);127128DIEValue &ValueRef =129*OutputDIE->addValue(Allocator, Attr, dwarf::DW_FORM_string, Block);130return std::pair<DIEValue &, size_t>(ValueRef, String.size() + 1);131}132133/// Creates appreviations for the current DIE. Returns value of134/// abbreviation number. Updates offsets with the size of abbreviation135/// number.136size_t finalizeAbbreviations(bool CHILDREN_yes,137OffsetsPtrVector *OffsetsList) {138// Create abbreviations for output DIE.139DIEAbbrev NewAbbrev = OutputDIE->generateAbbrev();140if (CHILDREN_yes)141NewAbbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);142143CU.assignAbbrev(NewAbbrev);144OutputDIE->setAbbrevNumber(NewAbbrev.getNumber());145146size_t AbbrevNumberSize = getULEB128Size(OutputDIE->getAbbrevNumber());147148// Add size of abbreviation number to the offsets.149if (OffsetsList != nullptr) {150for (uint64_t *OffsetPtr : *OffsetsList)151*OffsetPtr += AbbrevNumberSize;152}153154return AbbrevNumberSize;155}156157protected:158template <typename T>159std::pair<DIEValue &, size_t> addAttribute(dwarf::Attribute Attr,160dwarf::Form AttrForm, T &&Value) {161DIEValue &ValueRef =162*OutputDIE->addValue(Allocator, Attr, AttrForm, std::forward<T>(Value));163unsigned ValueSize = ValueRef.sizeOf(CU.getFormParams());164return std::pair<DIEValue &, size_t>(ValueRef, ValueSize);165}166167// Allocator for output DIEs and values.168BumpPtrAllocator &Allocator;169170// Unit for the output DIE.171DwarfUnit &CU;172173// OutputDIE.174DIE *OutputDIE = nullptr;175};176177} // end of namespace parallel178} // end of namespace dwarf_linker179} // end of namespace llvm180181#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DIEGENERATOR_H182183184