我最近发现,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)
  }


相当难以理解,但鞋子合脚。确保您的链接器使用这样的脚本。

09-26 12:22