| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 1 | //===- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework -----------===// | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 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 |  | 
|  | 10 | #include "DwarfStringPool.h" | 
| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 11 | #include "llvm/ADT/SmallVector.h" | 
|  | 12 | #include "llvm/ADT/StringRef.h" | 
|  | 13 | #include "llvm/ADT/Twine.h" | 
| Duncan P. N. Exon Smith | 9d50e82 | 2015-05-24 16:54:59 +0000 | [diff] [blame] | 14 | #include "llvm/CodeGen/AsmPrinter.h" | 
| Duncan P. N. Exon Smith | 882a2b5 | 2015-05-24 16:58:59 +0000 | [diff] [blame] | 15 | #include "llvm/MC/MCAsmInfo.h" | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 16 | #include "llvm/MC/MCStreamer.h" | 
| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 17 | #include <cassert> | 
|  | 18 | #include <utility> | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 19 |  | 
|  | 20 | using namespace llvm; | 
|  | 21 |  | 
| Duncan P. N. Exon Smith | 882a2b5 | 2015-05-24 16:58:59 +0000 | [diff] [blame] | 22 | DwarfStringPool::DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm, | 
|  | 23 | StringRef Prefix) | 
|  | 24 | : Pool(A), Prefix(Prefix), | 
|  | 25 | ShouldCreateSymbols(Asm.MAI->doesDwarfUseRelocationsAcrossSections()) {} | 
|  | 26 |  | 
| Duncan P. N. Exon Smith | 03b7a1c | 2015-05-24 16:33:33 +0000 | [diff] [blame] | 27 | DwarfStringPool::EntryRef DwarfStringPool::getEntry(AsmPrinter &Asm, | 
| Duncan P. N. Exon Smith | 1a65e4a | 2015-05-24 16:14:59 +0000 | [diff] [blame] | 28 | StringRef Str) { | 
| Duncan P. N. Exon Smith | 03b7a1c | 2015-05-24 16:33:33 +0000 | [diff] [blame] | 29 | auto I = Pool.insert(std::make_pair(Str, EntryTy())); | 
|  | 30 | if (I.second) { | 
|  | 31 | auto &Entry = I.first->second; | 
| Duncan P. N. Exon Smith | 1a65e4a | 2015-05-24 16:14:59 +0000 | [diff] [blame] | 32 | Entry.Index = Pool.size() - 1; | 
|  | 33 | Entry.Offset = NumBytes; | 
| Duncan P. N. Exon Smith | 882a2b5 | 2015-05-24 16:58:59 +0000 | [diff] [blame] | 34 | Entry.Symbol = ShouldCreateSymbols ? Asm.createTempSymbol(Prefix) : nullptr; | 
| Duncan P. N. Exon Smith | 1a65e4a | 2015-05-24 16:14:59 +0000 | [diff] [blame] | 35 |  | 
|  | 36 | NumBytes += Str.size() + 1; | 
|  | 37 | assert(NumBytes > Entry.Offset && "Unexpected overflow"); | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 38 | } | 
| Duncan P. N. Exon Smith | 03b7a1c | 2015-05-24 16:33:33 +0000 | [diff] [blame] | 39 | return EntryRef(*I.first); | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 40 | } | 
|  | 41 |  | 
| Rafael Espindola | 0709a7b | 2015-05-21 19:20:38 +0000 | [diff] [blame] | 42 | void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection, | 
| Wolfgang Pieb | 456b555 | 2018-01-26 18:52:58 +0000 | [diff] [blame] | 43 | MCSection *OffsetSection, bool UseRelativeOffsets) { | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 44 | if (Pool.empty()) | 
|  | 45 | return; | 
|  | 46 |  | 
|  | 47 | // Start the dwarf str section. | 
| Lang Hames | 9ff69c8 | 2015-04-24 19:11:51 +0000 | [diff] [blame] | 48 | Asm.OutStreamer->SwitchSection(StrSection); | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 49 |  | 
|  | 50 | // Get all of the string pool entries and put them in an array by their ID so | 
|  | 51 | // we can sort them. | 
| Duncan P. N. Exon Smith | 1a65e4a | 2015-05-24 16:14:59 +0000 | [diff] [blame] | 52 | SmallVector<const StringMapEntry<EntryTy> *, 64> Entries(Pool.size()); | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 53 |  | 
|  | 54 | for (const auto &E : Pool) | 
| Duncan P. N. Exon Smith | 1a65e4a | 2015-05-24 16:14:59 +0000 | [diff] [blame] | 55 | Entries[E.getValue().Index] = &E; | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 56 |  | 
|  | 57 | for (const auto &Entry : Entries) { | 
| Duncan P. N. Exon Smith | 882a2b5 | 2015-05-24 16:58:59 +0000 | [diff] [blame] | 58 | assert(ShouldCreateSymbols == static_cast<bool>(Entry->getValue().Symbol) && | 
|  | 59 | "Mismatch between setting and entry"); | 
|  | 60 |  | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 61 | // Emit a label for reference from debug information entries. | 
| Duncan P. N. Exon Smith | 882a2b5 | 2015-05-24 16:58:59 +0000 | [diff] [blame] | 62 | if (ShouldCreateSymbols) | 
|  | 63 | Asm.OutStreamer->EmitLabel(Entry->getValue().Symbol); | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 64 |  | 
|  | 65 | // Emit the string itself with a terminating null byte. | 
| Duncan P. N. Exon Smith | 1a65e4a | 2015-05-24 16:14:59 +0000 | [diff] [blame] | 66 | Asm.OutStreamer->AddComment("string offset=" + | 
|  | 67 | Twine(Entry->getValue().Offset)); | 
| Lang Hames | 9ff69c8 | 2015-04-24 19:11:51 +0000 | [diff] [blame] | 68 | Asm.OutStreamer->EmitBytes( | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 69 | StringRef(Entry->getKeyData(), Entry->getKeyLength() + 1)); | 
|  | 70 | } | 
|  | 71 |  | 
|  | 72 | // If we've got an offset section go ahead and emit that now as well. | 
|  | 73 | if (OffsetSection) { | 
| Lang Hames | 9ff69c8 | 2015-04-24 19:11:51 +0000 | [diff] [blame] | 74 | Asm.OutStreamer->SwitchSection(OffsetSection); | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 75 | unsigned size = 4; // FIXME: DWARF64 is 8. | 
| Duncan P. N. Exon Smith | 1a65e4a | 2015-05-24 16:14:59 +0000 | [diff] [blame] | 76 | for (const auto &Entry : Entries) | 
| Wolfgang Pieb | 456b555 | 2018-01-26 18:52:58 +0000 | [diff] [blame] | 77 | if (UseRelativeOffsets) | 
|  | 78 | Asm.emitDwarfStringOffset(Entry->getValue()); | 
|  | 79 | else | 
|  | 80 | Asm.OutStreamer->EmitIntValue(Entry->getValue().Offset, size); | 
| David Blaikie | daefdbf | 2014-04-25 21:34:35 +0000 | [diff] [blame] | 81 | } | 
|  | 82 | } |