LLVM  13.0.0git
DwarfStringPool.cpp
Go to the documentation of this file.
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "DwarfStringPool.h"
10 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/ADT/Twine.h"
13 #include "llvm/MC/MCAsmInfo.h"
14 #include "llvm/MC/MCStreamer.h"
15 #include <cassert>
16 #include <utility>
17 
18 using namespace llvm;
19 
22  : Pool(A), Prefix(Prefix),
23  ShouldCreateSymbols(Asm.MAI->doesDwarfUseRelocationsAcrossSections()) {}
24 
26 DwarfStringPool::getEntryImpl(AsmPrinter &Asm, StringRef Str) {
27  auto I = Pool.insert(std::make_pair(Str, EntryTy()));
28  auto &Entry = I.first->second;
29  if (I.second) {
30  Entry.Index = EntryTy::NotIndexed;
31  Entry.Offset = NumBytes;
32  Entry.Symbol = ShouldCreateSymbols ? Asm.createTempSymbol(Prefix) : nullptr;
33 
34  NumBytes += Str.size() + 1;
35  }
36  return *I.first;
37 }
38 
40  StringRef Str) {
41  auto &MapEntry = getEntryImpl(Asm, Str);
42  return EntryRef(MapEntry, false);
43 }
44 
46  StringRef Str) {
47  auto &MapEntry = getEntryImpl(Asm, Str);
48  if (!MapEntry.getValue().isIndexed())
49  MapEntry.getValue().Index = NumIndexedStrings++;
50  return EntryRef(MapEntry, true);
51 }
52 
55  MCSymbol *StartSym) {
56  if (getNumIndexedStrings() == 0)
57  return;
58  Asm.OutStreamer->SwitchSection(Section);
59  unsigned EntrySize = Asm.getDwarfOffsetByteSize();
60  // We are emitting the header for a contribution to the string offsets
61  // table. The header consists of an entry with the contribution's
62  // size (not including the size of the length field), the DWARF version and
63  // 2 bytes of padding.
64  Asm.emitDwarfUnitLength(getNumIndexedStrings() * EntrySize + 4,
65  "Length of String Offsets Set");
66  Asm.emitInt16(Asm.getDwarfVersion());
67  Asm.emitInt16(0);
68  // Define the symbol that marks the start of the contribution. It is
69  // referenced by most unit headers via DW_AT_str_offsets_base.
70  // Split units do not use the attribute.
71  if (StartSym)
72  Asm.OutStreamer->emitLabel(StartSym);
73 }
74 
76  MCSection *OffsetSection, bool UseRelativeOffsets) {
77  if (Pool.empty())
78  return;
79 
80  // Start the dwarf str section.
81  Asm.OutStreamer->SwitchSection(StrSection);
82 
83  // Get all of the string pool entries and sort them by their offset.
85  Entries.reserve(Pool.size());
86 
87  for (const auto &E : Pool)
88  Entries.push_back(&E);
89 
90  llvm::sort(Entries, [](const StringMapEntry<EntryTy> *A,
91  const StringMapEntry<EntryTy> *B) {
92  return A->getValue().Offset < B->getValue().Offset;
93  });
94 
95  for (const auto &Entry : Entries) {
96  assert(ShouldCreateSymbols == static_cast<bool>(Entry->getValue().Symbol) &&
97  "Mismatch between setting and entry");
98 
99  // Emit a label for reference from debug information entries.
100  if (ShouldCreateSymbols)
101  Asm.OutStreamer->emitLabel(Entry->getValue().Symbol);
102 
103  // Emit the string itself with a terminating null byte.
104  Asm.OutStreamer->AddComment("string offset=" +
105  Twine(Entry->getValue().Offset));
106  Asm.OutStreamer->emitBytes(
107  StringRef(Entry->getKeyData(), Entry->getKeyLength() + 1));
108  }
109 
110  // If we've got an offset section go ahead and emit that now as well.
111  if (OffsetSection) {
112  // Now only take the indexed entries and put them in an array by their ID so
113  // we can emit them in order.
114  Entries.resize(NumIndexedStrings);
115  for (const auto &Entry : Pool) {
116  if (Entry.getValue().isIndexed())
117  Entries[Entry.getValue().Index] = &Entry;
118  }
119 
120  Asm.OutStreamer->SwitchSection(OffsetSection);
121  unsigned size = Asm.getDwarfOffsetByteSize();
122  for (const auto &Entry : Entries)
123  if (UseRelativeOffsets)
124  Asm.emitDwarfStringOffset(Entry->getValue());
125  else
126  Asm.OutStreamer->emitIntValue(Entry->getValue().Offset, size);
127  }
128 }
llvm::DwarfStringPool::getEntry
EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
Definition: DwarfStringPool.cpp:39
AsmPrinter.h
llvm
This class represents lattice values for constants.
Definition: AllocatorList.h:23
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::StringMapEntry
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
Definition: StringMapEntry.h:69
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:161
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::DwarfStringPool::EntryRef
DwarfStringPoolEntryRef EntryRef
Definition: DwarfStringPool.h:38
llvm::DwarfStringPool::getIndexedEntry
EntryRef getIndexedEntry(AsmPrinter &Asm, StringRef Str)
Same as getEntry, except that you can use EntryRef::getIndex to obtain a unique ID of this entry (e....
Definition: DwarfStringPool.cpp:45
llvm::DwarfStringPoolEntryRef
String pool entry reference.
Definition: DwarfStringPoolEntry.h:31
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:78
llvm::DwarfStringPoolEntry::NotIndexed
static constexpr unsigned NotIndexed
Definition: DwarfStringPoolEntry.h:21
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Twine.h
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::DwarfStringPool::size
unsigned size() const
Definition: DwarfStringPool.h:51
llvm::DwarfStringPool::emitStringOffsetsTableHeader
void emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSection *OffsetSection, MCSymbol *StartSym)
Definition: DwarfStringPool.cpp:53
llvm::BumpPtrAllocatorImpl
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
llvm::DwarfStringPool::getNumIndexedStrings
unsigned getNumIndexedStrings() const
Definition: DwarfStringPool.h:53
I
#define I(x, y, z)
Definition: MD5.cpp:59
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCAsmInfo.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::DwarfStringPool::emit
void emit(AsmPrinter &Asm, MCSection *StrSection, MCSection *OffsetSection=nullptr, bool UseRelativeOffsets=false)
Definition: DwarfStringPool.cpp:75
llvm::MCSection
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
llvm::DwarfStringPool::DwarfStringPool
DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm, StringRef Prefix)
Definition: DwarfStringPool.cpp:20
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1439
llvm::AsmPrinter
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:82
SmallVector.h
MCStreamer.h
llvm::HexStyle::Asm
@ Asm
0ffh
Definition: MCInstPrinter.h:34
DwarfStringPool.h
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:160