summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/tools/dsymutil/DwarfLinker.cpp58
-rw-r--r--llvm/tools/dsymutil/MachOUtils.cpp13
-rw-r--r--llvm/tools/dsymutil/NonRelocatableStringpool.h50
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
OpenPOWER on IntegriCloud