summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/PEImage.cpp53
-rw-r--r--src/PEImage.h10
-rw-r--r--src/dwarf2pdb.cpp1
3 files changed, 38 insertions, 26 deletions
diff --git a/src/PEImage.cpp b/src/PEImage.cpp
index 63f57de..4c4afff 100644
--- a/src/PEImage.cpp
+++ b/src/PEImage.cpp
@@ -783,40 +783,41 @@ const char* PEImage::findSectionSymbolName(int s) const
return t_findSectionSymbolName<IMAGE_SYMBOL> (s);
}
-bool symbolMatches(const char* name, const char* symname, bool& dllimport)
+void PEImage::createSymbolCache()
{
- if (strcmp(symname, name) == 0)
- return true;
- if (symname[0] != '_')
- return false;
- if (strcmp(symname + 1, name) == 0)
- return true;
-
- if (strncmp(symname + 1, "_imp_", 5) == 0)
- symname += 6;
- else
- return false;
- if (strcmp(symname, name) != 0 && (symname[0] != '_' || strcmp(symname + 1, name) != 0))
- return false;
- dllimport = true;
- return true;
-}
-
-int PEImage::findSymbol(const char* name, unsigned long& off, bool& dllimport) const
-{
- int sizeof_sym = bigobj ? sizeof(IMAGE_SYMBOL_EX) : IMAGE_SIZEOF_SYMBOL;
- for(int i = 0; i < nsym; i++)
+ int sizeof_sym = bigobj ? sizeof(IMAGE_SYMBOL_EX) : IMAGE_SIZEOF_SYMBOL;
+ for (int i = 0; i < nsym; ++i)
{
- IMAGE_SYMBOL* sym = (IMAGE_SYMBOL*) (symtable + i * sizeof_sym);
+ IMAGE_SYMBOL* sym = (IMAGE_SYMBOL*)(symtable + i * sizeof_sym);
const char* symname = sym->N.Name.Short == 0 ? strtable + sym->N.Name.Long : (char*)sym->N.ShortName;
int seg = bigobj ? ((IMAGE_SYMBOL_EX*)sym)->SectionNumber : sym->SectionNumber;
- if(seg && symbolMatches(name, symname, dllimport))
+ if (seg)
{
- off = sym->Value;
- return seg - 1;
+ unsigned long off = sym->Value;
+ std::string key = symname;
+ bool dllimport = !key.compare(0, 6, "__imp_"); // symname starts with "__imp_"
+ symbolCache[key] = {seg, off, dllimport};
}
i += sym->NumberOfAuxSymbols;
}
+}
+
+int PEImage::findSymbol(const char* name, unsigned long& off, bool& dllimport) const
+{
+ std::string key = name;
+ auto it = symbolCache.find(key);
+ if (it == symbolCache.end())
+ it = symbolCache.find("_" + key);
+ if (it == symbolCache.end())
+ it = symbolCache.find("__imp_" + key);
+ if (it == symbolCache.end())
+ it = symbolCache.find("__imp__" + key);
+ if (it != symbolCache.end())
+ {
+ off = it->second.off;
+ dllimport = it->second.dllimport;
+ return it->second.seg - 1;
+ }
return -1;
}
diff --git a/src/PEImage.h b/src/PEImage.h
index 058dfc8..c014dd2 100644
--- a/src/PEImage.h
+++ b/src/PEImage.h
@@ -10,10 +10,18 @@
#include "LastError.h"
#include <windows.h>
+#include <unordered_map>
struct OMFDirHeader;
struct OMFDirEntry;
+struct SymbolInfo
+{
+ int seg;
+ unsigned long off;
+ bool dllimport;
+};
+
#define IMGHDR(x) (hdr32 ? hdr32->x : hdr64->x)
class PEImage : public LastError
@@ -93,6 +101,7 @@ public:
int dumpDebugLineInfoCOFF();
int dumpDebugLineInfoOMF();
+ void createSymbolCache();
private:
bool _initFromCVDebugDir(IMAGE_DEBUG_DIRECTORY* ddir);
@@ -118,6 +127,7 @@ private:
bool x64; // targets 64-bit machine
bool bigobj;
bool dbgfile; // is DBG file
+ std::unordered_map<std::string, SymbolInfo> symbolCache;
public:
//dwarf
diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp
index c828d37..bc030e6 100644
--- a/src/dwarf2pdb.cpp
+++ b/src/dwarf2pdb.cpp
@@ -1402,6 +1402,7 @@ bool CV2PDB::mapTypes()
bool CV2PDB::createTypes()
{
+ img.createSymbolCache();
mspdb::Mod* mod = globalMod();
int typeID = nextUserType;
int pointerAttr = img.isX64() ? 0x1000C : 0x800A;