How to resolve the GHC error "Unknown PEi386 section name `.idata$4' " on Windows?

667 views Asked by At

I recently found out that instructions I had written to compile HDBC-postgresql on Windows were no longer working with Haskell Platform 2012.2.0.0. The library builds alright, but when attempting to link the built library, cabal fails with:

Loading package HDBC-postgresql-2.3.2.1 ... ghc.exe: Unknown PEi386 section name
 `.idata$4' (while processing: C:/PROGRA~1/POSTGR~1/9.2/lib\libpq.a)
ghc.exe: panic! (the 'impossible' happened)
  (GHC version 7.4.1 for i386-unknown-mingw32):
        loadArchive "C:/PROGRA~1/POSTGR~1/9.2/lib\\libpq.a": failed

I tried re-making libpq.a with dlltool --no-idata4 --no-idata5, but then the error message changed to Unknown PEi386 section name `.idata$7'.

This seems to be GHC bug 7103.

According to the PE and COFF Specification, the dollar sign has a special meaning when included in section names, signaling a "grouped section". The linker is supposed to discard the "$" and all characters that follow it to create a merged .idata section, where the characters following the "$" are used to determine the ordering of contributions to the merged section.

Is there a way to force dlltool to not output grouped sections?

Alternatively, is there a way to take a GNU archive (A file), merge all grouped sections, and output the resulting merged import library (implib)?

EDIT: The same error happens with Haskell Platform 2012.4.0.0.

EDIT2 After looking at the source code of dlltool, there doesn't appear to be a way to force it not to output grouped sections. Also, I haven't found a ready-built utility that will merge grouped sections in an object file.

For the purpose of the bounty and this question, I am changing it to: How to construct a single .idata section given a module definition (DEF) file.

1

There are 1 answers

1
Hans Passant On

The linker is supposed to discard the "$" and all characters that follow it to create a merged .idata section

Yes, but that's only the default behavior of the Microsoft linker. I'm not up to speed enough on your tool-chain so just some hints. The gcc linker requires explicit config to merge the various .idata$x sections into a single .idata section. That's done by the SECTION directive. In mingw that appears to be done by a script, a sample one is available here. Note this part of the script:

  .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)
  }

Pretty inscrutable but the shoe fits. Make sure that your linker uses such a script.