brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · d304c7e Raw
125 lines · cpp
1//===- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework -----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "DwarfStringPool.h"10#include "llvm/ADT/SmallVector.h"11#include "llvm/ADT/Twine.h"12#include "llvm/CodeGen/AsmPrinter.h"13#include "llvm/MC/MCAsmInfo.h"14#include "llvm/MC/MCStreamer.h"15#include <cassert>16 17using namespace llvm;18 19DwarfStringPool::DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm,20                                 StringRef Prefix)21    : Pool(A), Prefix(Prefix),22      ShouldCreateSymbols(Asm.doesDwarfUseRelocationsAcrossSections()) {}23 24StringMapEntry<DwarfStringPool::EntryTy> &25DwarfStringPool::getEntryImpl(AsmPrinter &Asm, StringRef Str) {26  auto I = Pool.try_emplace(Str);27  auto &Entry = I.first->second;28  if (I.second) {29    Entry.Index = EntryTy::NotIndexed;30    Entry.Offset = NumBytes;31    Entry.Symbol = ShouldCreateSymbols ? Asm.createTempSymbol(Prefix) : nullptr;32 33    NumBytes += Str.size() + 1;34  }35  return *I.first;36}37 38DwarfStringPool::EntryRef DwarfStringPool::getEntry(AsmPrinter &Asm,39                                                    StringRef Str) {40  auto &MapEntry = getEntryImpl(Asm, Str);41  return EntryRef(MapEntry);42}43 44DwarfStringPool::EntryRef DwarfStringPool::getIndexedEntry(AsmPrinter &Asm,45                                                           StringRef Str) {46  auto &MapEntry = getEntryImpl(Asm, Str);47  if (!MapEntry.getValue().isIndexed())48    MapEntry.getValue().Index = NumIndexedStrings++;49  return EntryRef(MapEntry);50}51 52void DwarfStringPool::emitStringOffsetsTableHeader(AsmPrinter &Asm,53                                                   MCSection *Section,54                                                   MCSymbol *StartSym) {55  if (getNumIndexedStrings() == 0)56    return;57  Asm.OutStreamer->switchSection(Section);58  unsigned 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.63  Asm.emitDwarfUnitLength(getNumIndexedStrings() * EntrySize + 4,64                          "Length of String Offsets Set");65  Asm.emitInt16(Asm.getDwarfVersion());66  Asm.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.70  if (StartSym)71    Asm.OutStreamer->emitLabel(StartSym);72}73 74void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection,75                           MCSection *OffsetSection, bool UseRelativeOffsets) {76  if (Pool.empty())77    return;78 79  // Start the dwarf str section.80  Asm.OutStreamer->switchSection(StrSection);81 82  // Get all of the string pool entries and sort them by their offset.83  SmallVector<const StringMapEntry<EntryTy> *, 64> Entries(84      llvm::make_pointer_range(Pool));85 86  llvm::sort(Entries, [](const StringMapEntry<EntryTy> *A,87                         const StringMapEntry<EntryTy> *B) {88    return A->getValue().Offset < B->getValue().Offset;89  });90 91  for (const auto &Entry : Entries) {92    assert(ShouldCreateSymbols == static_cast<bool>(Entry->getValue().Symbol) &&93           "Mismatch between setting and entry");94 95    // Emit a label for reference from debug information entries.96    if (ShouldCreateSymbols)97      Asm.OutStreamer->emitLabel(Entry->getValue().Symbol);98 99    // Emit the string itself with a terminating null byte.100    Asm.OutStreamer->AddComment("string offset=" +101                                Twine(Entry->getValue().Offset));102    Asm.OutStreamer->emitBytes(103        StringRef(Entry->getKeyData(), Entry->getKeyLength() + 1));104  }105 106  // If we've got an offset section go ahead and emit that now as well.107  if (OffsetSection) {108    // Now only take the indexed entries and put them in an array by their ID so109    // we can emit them in order.110    Entries.resize(NumIndexedStrings);111    for (const auto &Entry : Pool) {112      if (Entry.getValue().isIndexed())113        Entries[Entry.getValue().Index] = &Entry;114    }115 116    Asm.OutStreamer->switchSection(OffsetSection);117    unsigned size = Asm.getDwarfOffsetByteSize();118    for (const auto &Entry : Entries)119      if (UseRelativeOffsets)120        Asm.emitDwarfStringOffset(Entry->getValue());121      else122        Asm.OutStreamer->emitIntValue(Entry->getValue().Offset, size);123  }124}125