diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | src/PEImage.cpp | 23 | ||||
-rw-r--r-- | src/PEImage.h | 2 | ||||
-rw-r--r-- | src/dwarf2pdb.cpp | 13 |
5 files changed, 39 insertions, 5 deletions
@@ -296,3 +296,7 @@ unreleased Version 0.22 * add support for char16_t and char32_t (emitted by dmd 2.089+ for dchar)
* fix loading 64-bit mspdb140.dll in VS2019
+
+2020-03-26 Version 0.48
+
+ * DWARF: add support for data symbols imported from DLL
@@ -1 +1 @@ -VERSION = 0.46
+VERSION = 0.48
diff --git a/src/PEImage.cpp b/src/PEImage.cpp index 5808cf9..1f916c2 100644 --- a/src/PEImage.cpp +++ b/src/PEImage.cpp @@ -783,14 +783,33 @@ const char* PEImage::findSectionSymbolName(int s) const return t_findSectionSymbolName<IMAGE_SYMBOL> (s);
}
-int PEImage::findSymbol(const char* name, unsigned long& off) const
+bool symbolMatches(const char* name, const char* symname, bool& dllimport)
+{
+ 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++)
{
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;
- if(strcmp(symname, name) == 0 || (symname[0] == '_' && strcmp(symname + 1, name) == 0))
+ if(symbolMatches(name, symname, dllimport))
{
off = sym->Value;
return bigobj ? ((IMAGE_SYMBOL_EX*)sym)->SectionNumber : sym->SectionNumber;
diff --git a/src/PEImage.h b/src/PEImage.h index 2935419..058dfc8 100644 --- a/src/PEImage.h +++ b/src/PEImage.h @@ -84,7 +84,7 @@ public: int countSections() const { return nsec; }
int findSection(unsigned int off) const;
- int findSymbol(const char* name, unsigned long& off) const;
+ int findSymbol(const char* name, unsigned long& off, bool& dllimport) const;
const char* findSectionSymbolName(int s) const;
const IMAGE_SECTION_HEADER& getSection(int s) const { return sec[s]; }
unsigned long long getImageBase() const { return IMGHDR(OptionalHeader.ImageBase); }
diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp index 191619b..70b6fc9 100644 --- a/src/dwarf2pdb.cpp +++ b/src/dwarf2pdb.cpp @@ -1584,9 +1584,14 @@ bool CV2PDB::createTypes() {
int seg = -1;
unsigned long segOff;
+ bool dllimport = false;
if (id.location.type == Invalid && id.external && id.linkage_name)
{
- seg = img.findSymbol(id.linkage_name, segOff);
+ seg = img.findSymbol(id.linkage_name, segOff, dllimport);
+ }
+ else if (id.location.type == Invalid && id.external)
+ {
+ seg = img.findSymbol(id.name, segOff, dllimport);
}
else
{
@@ -1602,6 +1607,12 @@ bool CV2PDB::createTypes() if (seg >= 0)
{
int type = getTypeByDWARFPtr(cu, id.type);
+ if (dllimport)
+ {
+ checkDWARFTypeAlloc(100);
+ cbDwarfTypes += addPointerType(dwarfTypes + cbDwarfTypes, type, pointerAttr | 0x20); // needs to be deduplicted?
+ type = nextDwarfType++;
+ }
appendGlobalVar(id.name, type, seg + 1, segOff);
int rc = mod->AddPublic2(id.name, seg + 1, segOff, type);
}
|