DwarfStringPool.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. //===-- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework ----------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "DwarfStringPool.h"
  10. #include "llvm/CodeGen/AsmPrinter.h"
  11. #include "llvm/MC/MCAsmInfo.h"
  12. #include "llvm/MC/MCStreamer.h"
  13. using namespace llvm;
  14. DwarfStringPool::DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm,
  15. StringRef Prefix)
  16. : Pool(A), Prefix(Prefix),
  17. ShouldCreateSymbols(Asm.MAI->doesDwarfUseRelocationsAcrossSections()) {}
  18. DwarfStringPool::EntryRef DwarfStringPool::getEntry(AsmPrinter &Asm,
  19. StringRef Str) {
  20. auto I = Pool.insert(std::make_pair(Str, EntryTy()));
  21. if (I.second) {
  22. auto &Entry = I.first->second;
  23. Entry.Index = Pool.size() - 1;
  24. Entry.Offset = NumBytes;
  25. Entry.Symbol = ShouldCreateSymbols ? Asm.createTempSymbol(Prefix) : nullptr;
  26. NumBytes += Str.size() + 1;
  27. assert(NumBytes > Entry.Offset && "Unexpected overflow");
  28. }
  29. return EntryRef(*I.first);
  30. }
  31. void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection,
  32. MCSection *OffsetSection) {
  33. if (Pool.empty())
  34. return;
  35. // Start the dwarf str section.
  36. Asm.OutStreamer->SwitchSection(StrSection);
  37. // Get all of the string pool entries and put them in an array by their ID so
  38. // we can sort them.
  39. SmallVector<const StringMapEntry<EntryTy> *, 64> Entries(Pool.size());
  40. for (const auto &E : Pool)
  41. Entries[E.getValue().Index] = &E;
  42. for (const auto &Entry : Entries) {
  43. assert(ShouldCreateSymbols == static_cast<bool>(Entry->getValue().Symbol) &&
  44. "Mismatch between setting and entry");
  45. // Emit a label for reference from debug information entries.
  46. if (ShouldCreateSymbols)
  47. Asm.OutStreamer->EmitLabel(Entry->getValue().Symbol);
  48. // Emit the string itself with a terminating null byte.
  49. Asm.OutStreamer->AddComment("string offset=" +
  50. Twine(Entry->getValue().Offset));
  51. Asm.OutStreamer->EmitBytes(
  52. StringRef(Entry->getKeyData(), Entry->getKeyLength() + 1));
  53. }
  54. // If we've got an offset section go ahead and emit that now as well.
  55. if (OffsetSection) {
  56. Asm.OutStreamer->SwitchSection(OffsetSection);
  57. unsigned size = 4; // FIXME: DWARF64 is 8.
  58. for (const auto &Entry : Entries)
  59. Asm.OutStreamer->EmitIntValue(Entry->getValue().Offset, size);
  60. }
  61. }