Generating correct .DEF files to export non-static functions AND GLOBALS

六月ゝ 毕业季﹏ 提交于 2019-12-12 18:34:39

问题


Following on from a question about detecting bad linkage to globals across dll boudaries, it turns out that I need to modify a .DEF file generator tool used by the PostgreSQL project so that it correctly emits DATA tags for .DEF entries for global variables.

Problem

I can't seem to find a way, using Microsoft's tools, to get a symbol table listing that differentiates between global variables and functions, and that includes globals that aren't initialized at their definition site.

Ideas?

Broken current approach

The tool loops over dumpbin /symbols output to generate the .DEF file. Unlike nm, which I'm used to, dumpbin /symbols does not appear to emit an entry for each symbol to indicate the symbol type - function, initialized variable, uninitialized variable. It only shows whether the symbol is locally defined or not.

With each dumpbin output line followed by the corresponding definition in the .c file, we have first an initialized global:

00B 00000000 SECT3  notype       External     | _DefaultXactIsoLevel
int         DefaultXactIsoLevel = XACT_READ_COMMITTED;

vs a function with non-static linkage:

022 00000030 SECT5  notype ()    External     | _IsAbortedTransactionBlockState
bool IsAbortedTransactionBlockState(void) {...}

... and for bonus fun, un-initialized globals appear to be shown as UNDEF, just like references to symbols from other compilation units, e.g:

007 00000004 UNDEF  notype       External     | _XactIsoLevel
int         XactIsoLevel;

even though this is pre-declared in the header during compilation (with project specific macro hand expanded for readability) as:

extern __declspec(dllexport) int XactIsoLevel;

So... it looks like dumpbin output doesn't contain enough information to generate a correct .DEF file.

Right now gendefs.pl is merrily spitting out a .DEF file that omits globals that aren't initialized, and declares everything else as code (by failing to specify CONSTANT or DATA in the .DEF). For something so broken, it's worked remarkably well.

Fixing it

To produce correct .DEF files, I need a way to determine which symbols are variables.

I looked at using cl.exe's /Fm option, but it's just a passthrough to the linker's /MAP option, and does nothing when you're just generating an object file, not linking it.

I could use a symbol dump tool that produces more useful information like gcc's nm.exe, but that adds extra tool dependencies and seems fragile.

At this point I am not able to simply annotate every exported function with PGDLLIMPORT (the __declspec(dllimport) / __declspec(dllexport) macro used by the project) and stop using a DEF file.

Even if I could I need to find an approach that will cause clear linker errors when PGDLLIMPORT is omitted on an exposed variable.

So. Windows linker/compiler experts. Any ideas?


回答1:


Well, I must say I was wrong saying that microsoft tools doesn't use symbol type field at all.

1). cl doesn't use it to differentiate actual type info, but it stores information that you need:

  • 0x20 means function
  • 0x00 means not a function

PE/COFF specification, p. 46-47.

You may search for presence/abscence of () after symbol type (notype in your case) in dumpbin's output to find whether it is code or data.

2). Also, cl generates in obj files special section for linker which include export switch for every __declspec(dllexport) symbol in the form /export:symbol[,type].

3). And last, you can specify 'C++' external linkage and get symbols' types because of mangling.




回答2:


I just add to the other post.
dumpbin has a specific option, namely /headers, that clearly points out the Type as code or data, together with a list of other attributes.



来源:https://stackoverflow.com/questions/21593281/generating-correct-def-files-to-export-non-static-functions-and-globals

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!