[llvm] [llvm-symbolizer] nfc, use map instead of vector (PR #69552)
Chen Zheng via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 18 19:46:38 PDT 2023
https://github.com/chenzheng1030 created https://github.com/llvm/llvm-project/pull/69552
Use map instead of vector for the symbols, so that:
- don't need to sort after collecting all symbols
- easily handle of symbols with same addresses.
- efficiently find the symbol which has same address when adding a new symbol. (A follow up patch needs this functionality.)
>From 1e39f569ec6412303f568512d2df84885763c03a Mon Sep 17 00:00:00 2001
From: Chen Zheng <czhengsz at cn.ibm.com>
Date: Wed, 18 Oct 2023 04:47:01 -0400
Subject: [PATCH] nfc, use map instead of vector
---
.../Symbolize/SymbolizableObjectFile.h | 8 +--
.../Symbolize/SymbolizableObjectFile.cpp | 49 +++++++++----------
2 files changed, 24 insertions(+), 33 deletions(-)
diff --git a/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableObjectFile.h b/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableObjectFile.h
index 075dbe3e0e372ed..8a881acb010ac3c 100644
--- a/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableObjectFile.h
+++ b/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableObjectFile.h
@@ -17,6 +17,7 @@
#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
#include "llvm/Support/Error.h"
#include <cstdint>
+#include <map>
#include <memory>
#include <string>
#include <utility>
@@ -73,7 +74,6 @@ class SymbolizableObjectFile : public SymbolizableModule {
bool UntagAddresses;
struct SymbolDesc {
- uint64_t Addr;
// If size is 0, assume that symbol occupies the whole memory range up to
// the following symbol.
uint64_t Size;
@@ -82,12 +82,8 @@ class SymbolizableObjectFile : public SymbolizableModule {
// Non-zero if this is an ELF local symbol. See the comment in
// getNameFromSymbolTable.
uint32_t ELFLocalSymIdx;
-
- bool operator<(const SymbolDesc &RHS) const {
- return Addr != RHS.Addr ? Addr < RHS.Addr : Size < RHS.Size;
- }
};
- std::vector<SymbolDesc> Symbols;
+ std::map<uint64_t, SymbolDesc> Symbols;
// (index, filename) pairs of ELF STT_FILE symbols.
std::vector<std::pair<uint32_t, StringRef>> FileSymbols;
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
index 6b8068a531c05fa..3b5a0ce709f5c08 100644
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
@@ -70,20 +70,6 @@ SymbolizableObjectFile::create(const object::ObjectFile *Obj,
return std::move(E);
}
- std::vector<SymbolDesc> &SS = res->Symbols;
- // Sort by (Addr,Size,Name). If several SymbolDescs share the same Addr,
- // pick the one with the largest Size. This helps us avoid symbols with no
- // size information (Size=0).
- llvm::stable_sort(SS);
- auto I = SS.begin(), E = SS.end(), J = SS.begin();
- while (I != E) {
- auto OI = I;
- while (++I != E && OI->Addr == I->Addr) {
- }
- *J++ = I[-1];
- }
- SS.erase(J, SS.end());
-
return std::move(res);
}
@@ -134,7 +120,10 @@ Error SymbolizableObjectFile::addCoffExportSymbols(
uint32_t NextOffset = I != E ? I->Offset : Export.Offset + 1;
uint64_t SymbolStart = ImageBase + Export.Offset;
uint64_t SymbolSize = NextOffset - Export.Offset;
- Symbols.push_back({SymbolStart, SymbolSize, Export.Name, 0});
+ // If the SymbolStart exists, use the one with the large Size.
+ // This helps us avoid symbols with no size information (Size = 0).
+ if (!Symbols.count(SymbolStart) || SymbolSize >= Symbols[SymbolStart].Size)
+ Symbols[SymbolStart] = {SymbolSize, Export.Name, 0};
}
return Error::success();
}
@@ -215,7 +204,14 @@ Error SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol,
if (Obj.isELF() && ELFSymbolRef(Symbol).getBinding() != ELF::STB_LOCAL)
ELFSymIdx = 0;
- Symbols.push_back({SymbolAddress, SymbolSize, SymbolName, ELFSymIdx});
+
+ // If the SymbolAddress exists, use the one with the large Size.
+ // This helps us avoid symbols with no size information (Size = 0).
+ if (!Symbols.count(SymbolAddress) ||
+ SymbolSize >= Symbols[SymbolAddress].Size) {
+ Symbols[SymbolAddress] = {SymbolSize, SymbolName, ELFSymIdx};
+ }
+
return Error::success();
}
@@ -234,26 +230,25 @@ uint64_t SymbolizableObjectFile::getModulePreferredBase() const {
bool SymbolizableObjectFile::getNameFromSymbolTable(
uint64_t Address, std::string &Name, uint64_t &Addr, uint64_t &Size,
std::string &FileName) const {
- SymbolDesc SD{Address, UINT64_C(-1), StringRef(), 0};
- auto SymbolIterator = llvm::upper_bound(Symbols, SD);
+ auto SymbolIterator = Symbols.upper_bound(Address);
if (SymbolIterator == Symbols.begin())
return false;
--SymbolIterator;
- if (SymbolIterator->Size != 0 &&
- SymbolIterator->Addr + SymbolIterator->Size <= Address)
+
+ auto &SD = SymbolIterator->second;
+ if (SD.Size != 0 && SymbolIterator->first + SD.Size <= Address)
return false;
- Name = SymbolIterator->Name.str();
- Addr = SymbolIterator->Addr;
- Size = SymbolIterator->Size;
+ Name = SD.Name.str();
+ Addr = SymbolIterator->first;
+ Size = SD.Size;
- if (SymbolIterator->ELFLocalSymIdx != 0) {
+ if (SD.ELFLocalSymIdx != 0) {
// If this is an ELF local symbol, find the STT_FILE symbol preceding
// SymbolIterator to get the filename. The ELF spec requires the STT_FILE
// symbol (if present) precedes the other STB_LOCAL symbols for the file.
assert(Module->isELF());
- auto It = llvm::upper_bound(
- FileSymbols,
- std::make_pair(SymbolIterator->ELFLocalSymIdx, StringRef()));
+ auto It = llvm::upper_bound(FileSymbols,
+ std::make_pair(SD.ELFLocalSymIdx, StringRef()));
if (It != FileSymbols.begin())
FileName = It[-1].second.str();
}
More information about the llvm-commits
mailing list