Skip to content

Commit 1fbab57

Browse files
committed
Consider the entrypoint when determining exports
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.
1 parent 969e466 commit 1fbab57

File tree

2 files changed

+63
-15
lines changed

2 files changed

+63
-15
lines changed

CHANGES

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ Version 0.44
3030
as querying the compilers for their library search paths. Support parsing
3131
clang output.
3232
(Antonin Décimo, review by David Allsopp)
33-
- GPR#146: For mingw-w64, select crt2u.o instead of crt2.o if -link -municode
34-
is specified (David Allsopp)
33+
- GPR#146: Take the entrypoint (main, wmainCRTStartup, etc.) into account when
34+
determining the modules which will be linked. For mingw-w64, select crt2u.o
35+
instead of crt2.o if -link -municode is specified (David Allsopp)
3536

3637
Version 0.43
3738
- GPR#108: Add -lgcc_s to Cygwin's link libraries, upstreaming a patch from the

reloc.ml

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ let needed imported defined resolve_alias resolve_alternate obj =
725725
StrSet.empty
726726
obj.symbols
727727

728-
let build_dll link_exe output_file files exts extra_args =
728+
let build_dll link_exe output_file files exts extra_args_string =
729729
let main_pgm = link_exe <> `DLL in
730730

731731
(* fully resolve filenames, eliminate duplicates *)
@@ -1007,6 +1007,53 @@ let build_dll link_exe output_file files exts extra_args =
10071007
link_obj (Printf.sprintf "%s(%s)" libname objname) obj)
10081008
in
10091009

1010+
let entrypoint =
1011+
if not main_pgm then
1012+
None
1013+
else
1014+
match !toolchain with
1015+
| `CYGWIN64 ->
1016+
Some "main"
1017+
| `MINGW | `MINGW64 -> begin
1018+
let entry_point s =
1019+
String.length s > 7 && String.sub s 0 7 = "-Wl,-e,"
1020+
in
1021+
try
1022+
let s = List.find entry_point !extra_args in
1023+
Some (String.sub s 7 (String.length s - 7))
1024+
with Not_found ->
1025+
Some "mainCRTStartup"
1026+
end
1027+
| `MSVC | `MSVC64 -> begin
1028+
let entry_point s =
1029+
String.length s > 7 && String.lowercase_ascii (String.sub s 0 7) = "/entry:"
1030+
in
1031+
try
1032+
let s = List.find entry_point !extra_args in
1033+
Some (String.sub s 7 (String.length s - 7))
1034+
with Not_found ->
1035+
if !subsystem = "windows" then
1036+
Some "WinMainCRTStartup"
1037+
else
1038+
Some "mainCRTStartup"
1039+
end
1040+
| `LIGHTLD | `GNAT | `GNAT64 ->
1041+
None
1042+
in
1043+
let () =
1044+
match entrypoint with
1045+
| None -> ()
1046+
| Some entrypoint ->
1047+
try
1048+
let (libname, objname, _) as o = defined_in entrypoint in
1049+
if !explain then
1050+
Printf.printf "%s(%s) because of entrypoint %s\n%!" libname objname
1051+
entrypoint;
1052+
link_libobj o
1053+
with Not_found ->
1054+
if !explain then
1055+
Printf.printf "Entrypoint %s not found\n%!" entrypoint
1056+
in
10101057
let redirect = Hashtbl.create 16 in
10111058
List.iter
10121059
(fun (fn, obj) ->
@@ -1142,24 +1189,24 @@ let build_dll link_exe output_file files exts extra_args =
11421189
being an empty file. *)
11431190
let c = open_out implib in output_string c "x"; close_out c;
11441191
let _impexp = add_temp (Filename.chop_suffix implib ".lib" ^ ".exp") in
1145-
let extra_args =
1146-
if !custom_crt then "/nodefaultlib:LIBCMT /nodefaultlib:MSVCRT " ^ extra_args
1147-
else "msvcrt.lib " ^ extra_args
1192+
let extra_args_string =
1193+
if !custom_crt then "/nodefaultlib:LIBCMT /nodefaultlib:MSVCRT " ^ extra_args_string
1194+
else "msvcrt.lib " ^ extra_args_string
11481195
in
11491196

1150-
let extra_args =
1151-
if !machine = `x64 then (Printf.sprintf "/base:%s " !base_addr) ^ extra_args else extra_args
1197+
let extra_args_string =
1198+
if !machine = `x64 then (Printf.sprintf "/base:%s " !base_addr) ^ extra_args_string else extra_args_string
11521199
in
11531200

1154-
let extra_args =
1201+
let extra_args_string =
11551202
(* FlexDLL doesn't process .voltbl sections correctly, so don't allow the linker
11561203
to process them. *)
11571204
let command =
11581205
if Sys.win32 then link ^ " /nologo /? | findstr EMITVOLATILEMETADATA > NUL"
11591206
else link ^ " /nologo '/?' | grep -iq emitvolatilemetadata >/dev/null" in
11601207
if Sys.command command = 0 then
1161-
"/EMITVOLATILEMETADATA:NO " ^ extra_args
1162-
else extra_args
1208+
"/EMITVOLATILEMETADATA:NO " ^ extra_args_string
1209+
else extra_args_string
11631210
in
11641211

11651212
(* Flexdll requires that all images (main programs and all the DLLs) are
@@ -1187,7 +1234,7 @@ let build_dll link_exe output_file files exts extra_args =
11871234
(Filename.quote output_file)
11881235
!subsystem
11891236
files descr
1190-
extra_args
1237+
extra_args_string
11911238
| `CYGWIN64 ->
11921239
let def_file =
11931240
if main_pgm then ""
@@ -1209,7 +1256,7 @@ let build_dll link_exe output_file files exts extra_args =
12091256
descr
12101257
files
12111258
def_file
1212-
extra_args
1259+
extra_args_string
12131260
| `MINGW | `MINGW64 | `GNAT | `GNAT64 ->
12141261
let def_file =
12151262
if main_pgm then ""
@@ -1233,7 +1280,7 @@ let build_dll link_exe output_file files exts extra_args =
12331280
files
12341281
def_file
12351282
(if !implib then "-Wl,--out-implib=" ^ Filename.quote (Filename.chop_extension output_file ^ ".a") else "")
1236-
extra_args
1283+
extra_args_string
12371284
| `LIGHTLD ->
12381285
no_merge_manifest := true;
12391286
let ld = Option.value !Cmdline.use_linker ~default:"ld" in
@@ -1246,7 +1293,7 @@ let build_dll link_exe output_file files exts extra_args =
12461293
descr
12471294
files
12481295
(if !implib then "--out-implib " ^ Filename.quote (Filename.chop_extension output_file ^ ".a") else "")
1249-
extra_args
1296+
extra_args_string
12501297
in
12511298
debug ~dry_mode 1 "+ %s" cmd;
12521299
if not !dry_mode then begin

0 commit comments

Comments
 (0)