diff options
| -rw-r--r-- | llvm/tools/dsymutil/DwarfLinker.cpp | 58 | ||||
| -rw-r--r-- | llvm/tools/dsymutil/MachOUtils.cpp | 13 | ||||
| -rw-r--r-- | llvm/tools/dsymutil/NonRelocatableStringpool.h | 50 |
3 files changed, 64 insertions, 57 deletions
diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp index 0f5713b6b4f..cd61b5a2ed9 100644 --- a/llvm/tools/dsymutil/DwarfLinker.cpp +++ b/llvm/tools/dsymutil/DwarfLinker.cpp @@ -775,10 +775,13 @@ void DwarfStreamer::emitDIE(DIE &Die) { /// Emit the debug_str section stored in \p Pool. void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) { Asm->OutStreamer->SwitchSection(MOFI->getDwarfStrSection()); - for (auto *Entry = Pool.getFirstEntry(); Entry; - Entry = Pool.getNextEntry(Entry)) + std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntries(); + for (auto Entry : Entries) { + if (Entry.getIndex() == -1U) + break; Asm->OutStreamer->EmitBytes( - StringRef(Entry->getKey().data(), Entry->getKey().size() + 1)); + StringRef(Entry.getString().data(), Entry.getString().size() + 1)); + } } /// Emit the swift_ast section stored in \p Buffers. @@ -3697,28 +3700,23 @@ bool DwarfLinker::link(const DebugMap &Map) { return Options.NoOutput ? true : Streamer->finish(Map); } -/// Get the offset of string \p S in the string table. This -/// can insert a new element or return the offset of a preexisitng -/// one. -uint32_t NonRelocatableStringpool::getStringOffset(StringRef S) { +DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) { if (S.empty() && !Strings.empty()) - return 0; - - std::pair<uint32_t, StringMapEntryBase *> Entry(0, nullptr); - MapTy::iterator It; - bool Inserted; + return EmptyString; - // A non-empty string can't be at offset 0, so if we have an entry - // with a 0 offset, it must be a previously interned string. - std::tie(It, Inserted) = Strings.insert(std::make_pair(S, Entry)); - if (Inserted || It->getValue().first == 0) { - // Set offset and chain at the end of the entries list. - It->getValue().first = CurrentEndOffset; - CurrentEndOffset += S.size() + 1; // +1 for the '\0'. - Last->getValue().second = &*It; - Last = &*It; + auto I = Strings.insert(std::make_pair(S, DwarfStringPoolEntry())); + auto &Entry = I.first->second; + if (I.second || Entry.Index == -1U) { + Entry.Index = NumEntries++; + Entry.Offset = CurrentEndOffset; + Entry.Symbol = nullptr; + CurrentEndOffset += S.size() + 1; } - return It->getValue().first; + return DwarfStringPoolEntryRef(*I.first); +} + +uint32_t NonRelocatableStringpool::getStringOffset(StringRef S) { + return getEntry(S).getOffset(); } /// Put \p S into the StringMap so that it gets permanent @@ -3726,11 +3724,25 @@ uint32_t NonRelocatableStringpool::getStringOffset(StringRef S) { /// that go into the output section. A latter call to /// getStringOffset() with the same string will chain it though. StringRef NonRelocatableStringpool::internString(StringRef S) { - std::pair<uint32_t, StringMapEntryBase *> Entry(0, nullptr); + DwarfStringPoolEntry Entry{nullptr, 0, -1U}; auto InsertResult = Strings.insert(std::make_pair(S, Entry)); return InsertResult.first->getKey(); } +std::vector<DwarfStringPoolEntryRef> +NonRelocatableStringpool::getEntries() const { + std::vector<DwarfStringPoolEntryRef> Result; + Result.reserve(Strings.size()); + for (const auto &E : Strings) + Result.emplace_back(E); + std::sort( + Result.begin(), Result.end(), + [](const DwarfStringPoolEntryRef A, const DwarfStringPoolEntryRef B) { + return A.getIndex() < B.getIndex(); + }); + return Result; +} + void warn(const Twine &Warning, const Twine &Context) { errs() << Twine("while processing ") + Context + ":\n"; errs() << Twine("warning: ") + Warning + "\n"; diff --git a/llvm/tools/dsymutil/MachOUtils.cpp b/llvm/tools/dsymutil/MachOUtils.cpp index 06d0f72a61c..9035e947c54 100644 --- a/llvm/tools/dsymutil/MachOUtils.cpp +++ b/llvm/tools/dsymutil/MachOUtils.cpp @@ -493,11 +493,14 @@ bool generateDsymCompanion(const DebugMap &DM, MCStreamer &MS, // Reproduce that behavior for now (there is corresponding code in // transferSymbol). Writer.WriteZeros(1); - typedef NonRelocatableStringpool::MapTy MapTy; - for (auto *Entry = NewStrings.getFirstEntry(); Entry; - Entry = static_cast<MapTy::MapEntryTy *>(Entry->getValue().second)) - Writer.writeBytes( - StringRef(Entry->getKey().data(), Entry->getKey().size() + 1)); + std::vector<DwarfStringPoolEntryRef> Strings = NewStrings.getEntries(); + for (auto EntryRef : Strings) { + if (EntryRef.getIndex() == -1U) + break; + StringRef ZeroTerminated(EntryRef.getString().data(), + EntryRef.getString().size() + 1); + Writer.writeBytes(ZeroTerminated); + } } assert(OutFile.tell() == StringStart + NewStringsSize); diff --git a/llvm/tools/dsymutil/NonRelocatableStringpool.h b/llvm/tools/dsymutil/NonRelocatableStringpool.h index aa21d77ad43..57d8d5c05af 100644 --- a/llvm/tools/dsymutil/NonRelocatableStringpool.h +++ b/llvm/tools/dsymutil/NonRelocatableStringpool.h @@ -12,6 +12,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/DwarfStringPoolEntry.h" #include "llvm/Support/Allocator.h" #include <cstdint> #include <utility> @@ -19,54 +20,45 @@ namespace llvm { namespace dsymutil { -/// \brief A string table that doesn't need relocations. +/// A string table that doesn't need relocations. /// -/// We are doing a final link, no need for a string table that -/// has relocation entries for every reference to it. This class -/// provides this ablitity by just associating offsets with -/// strings. +/// We are doing a final link, no need for a string table that has relocation +/// entries for every reference to it. This class provides this ablitity by +/// just associating offsets with strings. class NonRelocatableStringpool { public: - /// \brief Entries are stored into the StringMap and simply linked - /// together through the second element of this pair in order to - /// keep track of insertion order. - using MapTy = - StringMap<std::pair<uint32_t, StringMapEntryBase *>, BumpPtrAllocator>; + /// Entries are stored into the StringMap and simply linked together through + /// the second element of this pair in order to keep track of insertion + /// order. + using MapTy = StringMap<DwarfStringPoolEntry, BumpPtrAllocator>; - NonRelocatableStringpool() : Sentinel(0), Last(&Sentinel) { + NonRelocatableStringpool() { // Legacy dsymutil puts an empty string at the start of the line // table. - getStringOffset(""); + EmptyString = getEntry(""); } - /// \brief Get the offset of string \p S in the string table. This - /// can insert a new element or return the offset of a preexisitng - /// one. + DwarfStringPoolEntryRef getEntry(StringRef S); + + /// Get the offset of string \p S in the string table. This can insert a new + /// element or return the offset of a pre-exisitng one. uint32_t getStringOffset(StringRef S); - /// \brief Get permanent storage for \p S (but do not necessarily - /// emit \p S in the output section). + /// Get permanent storage for \p S (but do not necessarily emit \p S in the + /// output section). /// \returns The StringRef that points to permanent storage to use /// in place of \p S. StringRef internString(StringRef S); - // \brief Return the first entry of the string table. - const MapTy::MapEntryTy *getFirstEntry() const { - return getNextEntry(&Sentinel); - } - - // \brief Get the entry following \p E in the string table or null - // if \p E was the last entry. - const MapTy::MapEntryTy *getNextEntry(const MapTy::MapEntryTy *E) const { - return static_cast<const MapTy::MapEntryTy *>(E->getValue().second); - } - uint64_t getSize() { return CurrentEndOffset; } + std::vector<DwarfStringPoolEntryRef> getEntries() const; + private: MapTy Strings; uint32_t CurrentEndOffset = 0; - MapTy::MapEntryTy Sentinel, *Last; + unsigned NumEntries = 0; + DwarfStringPoolEntryRef EmptyString; }; } // end namespace dsymutil |

