This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/69880] New: Linking Windows resources + implicit 'default-manifest.o' creates bad .exe


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69880

            Bug ID: 69880
           Summary: Linking Windows resources + implicit
                    'default-manifest.o' creates bad .exe
           Product: gcc
           Version: 5.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vsz.bugzilla at emailuser dot net
  Target Milestone: ---

Hi,

Sorry for the ambiguous title, I'm not completely sure where/what is the
culprit yet. Please bear with me.

While migrating to MSYS2 and its own mingw-w64 (5.3.0) toolchain (from a
non-MSYS2 build of the same toolchain), I stumbled into a problem. When linking
an application that has its own Windows resource, including a Windows Manifest,
I noticed that the final .exe is not compressible with UPX (3.91) anymore, with
the error:
   upx: my.exe: CantPackException: superfluous data between sections

Further investigation revealed that MSYS2 comes with a _default Windows
manifest_, as part of the toolchain. They are packaged as
`*windows-default-manifest`.

The GCC patch below made this feature possible, by automatically linking a
default resource object, whenever it's found on disk:
   https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01378.html

The problem happens when the application is also supplying its own resource
object (like in my case), and above default resource object is found as well.
In this case _both_ objects get linked to the executable. It means that the
.exe now has _two_ manifests. This by itself is already an ambiguity and some
unnecessary bloat. But, the way these two objects are linked also causes the
second instance to be apparently "orphaned" between two valid sections (.rsrc
and .reloc in my particular case) of the executable.

This orphaned data seems to be confusing UPX, hence its fatal error.

The orphaned data can be discarded by using `strip -g test.exe` (or `strip
--strip-unneeded test.exe`). In my case it deleted the extra data, and UPX
worked again. I'm not sure this works in all possible cases though, and
unfortunately it strips other information too, f.e. digital signatures. Plus
this extra step requires a revamp of existing build scripts and tooling.

To my best knowledge mingw never handled linking multiple Windows resources
well, but so far this could be easily mitigated by either merging .rc files in
advance and/or avoiding to pass multiple resource objects explicitly. With the
newly added implicit object feature, such care can no longer be taken.

IMO it'd be nice to have option to disable picking up the implicit
`default-manifest.o` object (deleting it cannot always be done and/or cannot be
done cleanly), or even better automatically drop it if there is any user
supplied resource object. Cleverly merging them and dropping any duplicate
entries, while giving the user-supplied object a priority would also be
helpful, if feasible. Anyhow, the goal is to allow to have a _single_ manifest
in the final executable, controlled by the user.

Here's my original bug report with some more aspects/information, plus steps to
recreate a minimal example:
   https://github.com/Alexpux/MSYS2-packages/issues/454

-Viktor

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]