从关于检测到跨dll budaries的不良链接的问题之后,事实证明,我需要修改一个.def文件生成器工具,该工具由PostgreSQL Project使用 DATA
标签.DEF条目的全局变量。
问题
我似乎找不到使用Microsoft的工具来获取区分全局变量和函数的符号表的方法,其中包括在其定义网站中未初始化的全球。
想法?
断开电流方法
dumpbin /symbols
输出上的工具循环以生成.def文件。与我曾经用过的nm
不同,dumpbin /symbols
似乎没有为每个符号发出一个条目,以指示符号类型 - 函数,初始化变量,非初始化的变量。它仅显示该符号是否在本地定义。
在每条dumpbin
输出线时,然后是.c
文件中的相应定义,我们首先有一个初始化的全局:
00B 00000000 SECT3 notype External | _DefaultXactIsoLevel
int DefaultXactIsoLevel = XACT_READ_COMMITTED;
vs具有非静态链接的函数:
022 00000030 SECT5 notype () External | _IsAbortedTransactionBlockState
bool IsAbortedTransactionBlockState(void) {...}
...为了获得奖励,非判定的全球群体似乎显示为UNDEF
,就像引用其他编译单元的符号一样,例如:
007 00000004 UNDEF notype External | _XactIsoLevel
int XactIsoLevel;
即使在编译过程中预先确定了这一点(特定于项目的宏手为可读性扩展),为:
extern __declspec(dllexport) int XactIsoLevel;
因此...看起来dumpbin
输出不包含足够的信息来生成正确的.DEF
文件。
目前,gendefs.pl
正在精心吐出一个.DEF
文件,该文件省略了未初始化的Globals,并将所有内容声明为代码(通过未能在.def中指定CONSTANT
或DATA
)。对于如此折断的事情,它的工作非常好。
修复
要产生正确的.def文件,我需要一种方法来确定哪些符号是变量。
我看使用cl.exe
的/Fm
选项,但这只是链接器的/MAP
选项的传递,并且当您仅生成对象文件而不链接它时什么都不做。
我可以使用一个符号转储工具,该工具会产生更多有用的信息,例如GCC的nm.exe
,但这增加了额外的工具依赖性并看起来脆弱。
在这一点上,我无法简单地用PGDLLIMPORT
(项目使用的__declspec(dllimport)
/__declspec(dllexport)
宏)注释每个导出功能,然后停止使用DEF文件。
即使我可以找到一种方法,该方法将在暴露变量上省略PGDLLIMPORT
时会导致明显的链接器错误。
所以。Windows Linker/编译器专家。有什么想法吗?
好吧,我必须说我错了说Microsoft工具根本不使用符号类型字段。
1)。 cl
不使用它来区分实际类型信息,但它存储了您需要的信息:
-
0x20
表示功能 -
0x00
表示不是函数
pe/coff规范,p。46-47。
您可以在dumpbin
的输出中搜索符号类型后的()
(notype
)的存在/吸收,以查找它是code
还是data
。
2)。另外,cl
在obj
文件中生成链接器的特殊部分,其中包括/export:symbol[,type]
中每个__declspec(dllexport)
符号的export
开关。
3)。,最后,您可以指定'C '外部链接并获得符号类型。
我只是添加到另一篇文章中。
dumpbin
具有一个特定的选项,即/headers
,它清楚地指出了 type 为代码或 data ,以及其他属性的列表。/p>