Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
35271 views
//===- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework -----------===//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#include "DwarfStringPool.h"9#include "llvm/ADT/SmallVector.h"10#include "llvm/ADT/Twine.h"11#include "llvm/CodeGen/AsmPrinter.h"12#include "llvm/MC/MCAsmInfo.h"13#include "llvm/MC/MCStreamer.h"14#include <cassert>15#include <utility>1617using namespace llvm;1819DwarfStringPool::DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm,20StringRef Prefix)21: Pool(A), Prefix(Prefix),22ShouldCreateSymbols(Asm.doesDwarfUseRelocationsAcrossSections()) {}2324StringMapEntry<DwarfStringPool::EntryTy> &25DwarfStringPool::getEntryImpl(AsmPrinter &Asm, StringRef Str) {26auto I = Pool.insert(std::make_pair(Str, EntryTy()));27auto &Entry = I.first->second;28if (I.second) {29Entry.Index = EntryTy::NotIndexed;30Entry.Offset = NumBytes;31Entry.Symbol = ShouldCreateSymbols ? Asm.createTempSymbol(Prefix) : nullptr;3233NumBytes += Str.size() + 1;34}35return *I.first;36}3738DwarfStringPool::EntryRef DwarfStringPool::getEntry(AsmPrinter &Asm,39StringRef Str) {40auto &MapEntry = getEntryImpl(Asm, Str);41return EntryRef(MapEntry);42}4344DwarfStringPool::EntryRef DwarfStringPool::getIndexedEntry(AsmPrinter &Asm,45StringRef Str) {46auto &MapEntry = getEntryImpl(Asm, Str);47if (!MapEntry.getValue().isIndexed())48MapEntry.getValue().Index = NumIndexedStrings++;49return EntryRef(MapEntry);50}5152void DwarfStringPool::emitStringOffsetsTableHeader(AsmPrinter &Asm,53MCSection *Section,54MCSymbol *StartSym) {55if (getNumIndexedStrings() == 0)56return;57Asm.OutStreamer->switchSection(Section);58unsigned EntrySize = Asm.getDwarfOffsetByteSize();59// We are emitting the header for a contribution to the string offsets60// table. The header consists of an entry with the contribution's61// size (not including the size of the length field), the DWARF version and62// 2 bytes of padding.63Asm.emitDwarfUnitLength(getNumIndexedStrings() * EntrySize + 4,64"Length of String Offsets Set");65Asm.emitInt16(Asm.getDwarfVersion());66Asm.emitInt16(0);67// Define the symbol that marks the start of the contribution. It is68// referenced by most unit headers via DW_AT_str_offsets_base.69// Split units do not use the attribute.70if (StartSym)71Asm.OutStreamer->emitLabel(StartSym);72}7374void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection,75MCSection *OffsetSection, bool UseRelativeOffsets) {76if (Pool.empty())77return;7879// Start the dwarf str section.80Asm.OutStreamer->switchSection(StrSection);8182// Get all of the string pool entries and sort them by their offset.83SmallVector<const StringMapEntry<EntryTy> *, 64> Entries;84Entries.reserve(Pool.size());8586for (const auto &E : Pool)87Entries.push_back(&E);8889llvm::sort(Entries, [](const StringMapEntry<EntryTy> *A,90const StringMapEntry<EntryTy> *B) {91return A->getValue().Offset < B->getValue().Offset;92});9394for (const auto &Entry : Entries) {95assert(ShouldCreateSymbols == static_cast<bool>(Entry->getValue().Symbol) &&96"Mismatch between setting and entry");9798// Emit a label for reference from debug information entries.99if (ShouldCreateSymbols)100Asm.OutStreamer->emitLabel(Entry->getValue().Symbol);101102// Emit the string itself with a terminating null byte.103Asm.OutStreamer->AddComment("string offset=" +104Twine(Entry->getValue().Offset));105Asm.OutStreamer->emitBytes(106StringRef(Entry->getKeyData(), Entry->getKeyLength() + 1));107}108109// If we've got an offset section go ahead and emit that now as well.110if (OffsetSection) {111// Now only take the indexed entries and put them in an array by their ID so112// we can emit them in order.113Entries.resize(NumIndexedStrings);114for (const auto &Entry : Pool) {115if (Entry.getValue().isIndexed())116Entries[Entry.getValue().Index] = &Entry;117}118119Asm.OutStreamer->switchSection(OffsetSection);120unsigned size = Asm.getDwarfOffsetByteSize();121for (const auto &Entry : Entries)122if (UseRelativeOffsets)123Asm.emitDwarfStringOffset(Entry->getValue());124else125Asm.OutStreamer->emitIntValue(Entry->getValue().Offset, size);126}127}128129130