1dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//===-- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework ----------===//
2dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
3dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//                     The LLVM Compiler Infrastructure
4dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
5dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// This file is distributed under the University of Illinois Open Source
6dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// License. See LICENSE.TXT for details.
7dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
8dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//===----------------------------------------------------------------------===//
9dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
10dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "DwarfStringPool.h"
11dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCStreamer.h"
12dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
13dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesusing namespace llvm;
14dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
15dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMCSymbol *DwarfStringPool::getSectionSymbol() { return SectionSymbol; }
16dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
17dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic std::pair<MCSymbol *, unsigned> &
18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesgetEntry(AsmPrinter &Asm,
19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         StringMap<std::pair<MCSymbol *, unsigned>, BumpPtrAllocator &> &Pool,
20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         StringRef Prefix, StringRef Str) {
21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  std::pair<MCSymbol *, unsigned> &Entry =
22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Pool.GetOrCreateValue(Str).getValue();
23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Entry.first) {
24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Entry.second = Pool.size() - 1;
25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Entry.first = Asm.GetTempSymbol(Prefix, Entry.second);
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return Entry;
28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMCSymbol *DwarfStringPool::getSymbol(AsmPrinter &Asm, StringRef Str) {
31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return getEntry(Asm, Pool, Prefix, Str).first;
32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned DwarfStringPool::getIndex(AsmPrinter &Asm, StringRef Str) {
35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return getEntry(Asm, Pool, Prefix, Str).second;
36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DwarfStringPool::emit(AsmPrinter &Asm, const MCSection *StrSection,
39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           const MCSection *OffsetSection,
40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           const MCSymbol *StrSecSym) {
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Pool.empty())
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Start the dwarf str section.
45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Asm.OutStreamer.SwitchSection(StrSection);
46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Get all of the string pool entries and put them in an array by their ID so
48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // we can sort them.
49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SmallVector<const StringMapEntry<std::pair<MCSymbol *, unsigned>> *, 64>
50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Entries(Pool.size());
51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const auto &E : Pool)
53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Entries[E.getValue().second] = &E;
54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const auto &Entry : Entries) {
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Emit a label for reference from debug information entries.
57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Asm.OutStreamer.EmitLabel(Entry->getValue().first);
58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Emit the string itself with a terminating null byte.
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Asm.OutStreamer.EmitBytes(
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        StringRef(Entry->getKeyData(), Entry->getKeyLength() + 1));
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If we've got an offset section go ahead and emit that now as well.
65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (OffsetSection) {
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Asm.OutStreamer.SwitchSection(OffsetSection);
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned offset = 0;
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned size = 4; // FIXME: DWARF64 is 8.
69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (const auto &Entry : Entries) {
70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Asm.OutStreamer.EmitIntValue(offset, size);
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      offset += Entry->getKeyLength() + 1;
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
75