我最近发现,instructions I had written在Windows上编译HDBC-postgresql不再与Haskell Platform 2012.2.0.0一起使用。库可以正常构建,但是当尝试链接已构建的库时,cabal
失败,并显示:
正在加载软件包HDBC-postgresql-2.3.2.1 ... ghc.exe:未知的PEi386节名称
`.idata $ 4'(正在处理:C:/PROGRA~1/POSTGR~1/9.2/lib \ libpq.a)
ghc.exe:恐慌! (“不可能”发生)
(适用于i386-unknown-mingw32的GHC版本7.4.1):
loadArchive“ C:/PROGRA~1/POSTGR~1/9.2/lib \\ libpq.a”:失败
我尝试使用libpq.a
重新制作dlltool --no-idata4 --no-idata5
,但随后错误消息更改为Unknown PEi386 section name `.idata$7'
。
这似乎是GHC bug 7103。
根据PE and COFF Specification,美元符号在段名称中包含时具有特殊含义,表示“分组的段”。链接器应该丢弃“ $”及其后的所有字符以创建合并的.idata
部分,其中“ $”之后的字符用于确定对合并部分的贡献顺序。
有没有办法强制dlltool
不输出分组的节?
另外,是否有办法获取GNU存档(一个文件),合并所有分组的节,然后输出结果合并的导入库(implib)?
编辑:Haskell Platform 2012.4.0.0发生相同的错误。
EDIT2在查看the source code of dlltool
之后,似乎没有一种方法可以强制它不输出分组的节。另外,我还没有找到一个现成的实用程序,可以将分组的节合并到一个目标文件中。
出于赏金和这个问题的目的,我将其更改为:如何在给定模块定义(DEF)文件的情况下构造单个.idata
节。
最佳答案
链接器应该丢弃“ $”和其后的所有字符以创建合并的.idata节
是的,但这只是Microsoft链接程序的默认行为。我在您的工具链上还不够快,因此仅提供一些提示。 gcc链接器需要显式配置,以将各个.idata $ x节合并为一个.idata节。这是通过SECTION指令完成的。在mingw看来是由脚本完成的,其中一个示例可用here。请注意脚本的这一部分:
.idata BLOCK(__section_alignment__) :
{
/* This cannot currently be handled with grouped sections.
See pe.em:sort_sections. */
SORT(*)(.idata$2)
SORT(*)(.idata$3)
/* These zeroes mark the end of the import list. */
LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
SORT(*)(.idata$4)
__IAT_start__ = .;
SORT(*)(.idata$5)
__IAT_end__ = .;
SORT(*)(.idata$6)
SORT(*)(.idata$7)
}
相当难以理解,但鞋子合脚。确保您的链接器使用这样的脚本。