Ensure the entrypoint is taken into account when computing the export table#146
Open
dra27 wants to merge 4 commits intoocaml:masterfrom
Open
Ensure the entrypoint is taken into account when computing the export table#146dra27 wants to merge 4 commits intoocaml:masterfrom
dra27 wants to merge 4 commits intoocaml:masterfrom
Conversation
d08e8a0 to
63a7dbd
Compare
The defined_in function is used when determining which objects from the command line will actually be linked. However, this doesn't include the default libraries, which creates an issue for modules which are linked as a result of main. defined_in is augmented to include the mapping of symbols found in the default libraries, but some additional care is required to ensure that this doesn't cause imports from those to leak into the export table of the executable.
If -municode is passed to mingw-w64's gcc, then crt2u.o (which causes wmain to be selected) should be linked rather than crt2.o. In passing, the code now sniffs for -nostartfiles, which causes neither crt2.o nor crt2u.o to be considered.
The export table is determined by looping over the objects included on the command line. If the main symbol is included in a library (e.g. libcamlrun or libasmrun) then there may not be an object on the commandline which causes it, and any transitive dependencies, to be linked. The entrypoint symbol for the Cygwin/mingw-w64/MSVC toolchains is now resolved, and may cause additional objects to be linked.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Presently on trunk and - as far as I can tell - since OCaml 3.11, in Cygwin64:
This is strange, since ocaml/ocaml@27780d9#diff-3c8eb806a6be5e7baa5af9546b7e12cdfa1220daae562235a450f87b93dd06e7 in OCaml 3.12 ensures that
debugger.ois linked into OCaml programs precisely to prevent this problem. The symbol is indeed present:the issue is that it is not included in the flexlink export table:
$ PATH=opt/bin:$PATH ./boot/ocamlrun.exe ./ocamlopt.exe -nostdlib -I ./stdlib -I otherlibs/dynlink -I utils -I parsing -I typing -I bytecomp -I file_formats -I lambda -I middle_end -I middle_end/closure -I middle_end/flambda -I middle_end/flambda/base_types -I asmcomp -I driver -I toplevel -I tools -I runtime -I otherlibs/dynlink -I otherlibs/str -I otherlibs/systhreads -I otherlibs/unix -I otherlibs/runtime_events -g -linkall -I toplevel/native -o ocamlnat.exe compilerlibs/ocamlcommon.cmxa compilerlibs/ocamloptcomp.cmxa compilerlibs/ocamlbytecomp.cmxa otherlibs/dynlink/dynlink.cmxa compilerlibs/ocamltoplevel.cmxa toplevel/topstart.cmx -cclib -show-exports | fgrep caml_debugger_in_useThe reason is that while
-lasmrunis passed to flexlink, the objects passed on the command line give flexlink no reason to linkstartup_nat.n.o, which would then causedebugger.n.oto be considered and consequently these symbols to be added to the export table.The fundamental fix here is that when linking an executable, flexlink now considers the entry point when closing over the required list of objects. For Cygwin, this fix is quite simple as it suffices to consider linking
main. Cygwin's gcc does linkcrt0.o, but the full mechanism is technically a bit more involved. This doesn't matter, though, because being a Posix system, the entrypoint is alwaysmain(notwmainorWinMain/wWinMain, etc.).For both MSVC and mingw-w64, the fix is a little more complex as, being non-Posix, there's not a strict requirement for the entrypoint to be
main. For mingw-w64, the entrypoint ismainCRTStartup, but whether that callsmainorwmainis determined by-municodewhich selects between usingcrt2.oorcrt2u.oas the startup object. MSVC is affected both by the/ENTRYand/SUBSYSTEMlinker options, which select between one ofmainCRTStartup,wmainCRTStartup,WinMainCRTStartuporwWinMainCRTStartup.MSVCRT.libcontains each of those symbols in a separate object each of which then has an import reference to eithermain,wmain,WinMainorwWinMainas required. Since OCaml 4.06, OCaml therefore uses-municodefor mingw-w64 and/ENTRY:wMainCRTStartupfor MSVC.This leads to the main part of this PR - the entrypoint for mingw-w64 and MSVC is therefore defined not in one of the objects or libraries passed on the command line (i.e. in
libasmrun.a), but in one of the default libraries (eithercrt2u.oorMSVCRT.lib). The problem is that while these libraries are scanned, they are not analysed when closing over the objects which need to be linked. This is correct (the default libraries are assumed to be being linked in both executable and DLL) - but the objects should be considered in case they import symbols which do come from the objects and libraries passed on the command line. The changes here therefore mean that for mingw-w64,mainCRTStartupgets resolved tocrt2u.o. That module importswmainwhich then causesmain.n.ofromlibasmrun.ato be linked and, consequentlystartup_nat.n.oand hencedebugger.n.o. This PR happens to be an alternate fix (or, rather, workaround) for ocaml/ocaml#13520.