Skip to content

Commit d08e8a0

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 6559392 commit d08e8a0

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
@@ -23,8 +23,9 @@ Next version
2323
- GPR#133, GPR#147: Allow default libraries to be marked as optional (David Allsopp, report by Romain Beauxis)
2424
- GPR#157: Improve flexlink support on Unix (for cross-compiling contexts).
2525
(Antonin Décimo, review by David Allsopp)
26-
- GPR#146: For mingw-w64, select crt2u.o instead of crt2.o if -link -municode
27-
is specified (David Allsopp)
26+
- GPR#146: Take the entrypoint (main, wmainCRTStartup, etc.) into account when
27+
determining the modules which will be linked. For mingw-w64, select crt2u.o
28+
instead of crt2.o if -link -municode is specified (David Allsopp)
2829

2930
Version 0.43
3031
- 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
@@ -717,7 +717,7 @@ let needed imported defined resolve_alias resolve_alternate obj =
717717
StrSet.empty
718718
obj.symbols
719719

720-
let build_dll link_exe output_file files exts extra_args =
720+
let build_dll link_exe output_file files exts extra_args_string =
721721
let main_pgm = link_exe <> `DLL in
722722

723723
(* fully resolve filenames, eliminate duplicates *)
@@ -999,6 +999,53 @@ let build_dll link_exe output_file files exts extra_args =
999999
link_obj (Printf.sprintf "%s(%s)" libname objname) obj)
10001000
in
10011001

1002+
let entrypoint =
1003+
if not main_pgm then
1004+
None
1005+
else
1006+
match !toolchain with
1007+
| `CYGWIN64 ->
1008+
Some "main"
1009+
| `MINGW | `MINGW64 -> begin
1010+
let entry_point s =
1011+
String.length s > 7 && String.sub s 0 7 = "-Wl,-e,"
1012+
in
1013+
try
1014+
let s = List.find entry_point !extra_args in
1015+
Some (String.sub s 7 (String.length s - 7))
1016+
with Not_found ->
1017+
Some "mainCRTStartup"
1018+
end
1019+
| `MSVC | `MSVC64 -> begin
1020+
let entry_point s =
1021+
String.length s > 7 && String.lowercase_ascii (String.sub s 0 7) = "/entry:"
1022+
in
1023+
try
1024+
let s = List.find entry_point !extra_args in
1025+
Some (String.sub s 7 (String.length s - 7))
1026+
with Not_found ->
1027+
if !subsystem = "windows" then
1028+
Some "WinMainCRTStartup"
1029+
else
1030+
Some "mainCRTStartup"
1031+
end
1032+
| `LIGHTLD | `GNAT | `GNAT64 ->
1033+
None
1034+
in
1035+
let () =
1036+
match entrypoint with
1037+
| None -> ()
1038+
| Some entrypoint ->
1039+
try
1040+
let (libname, objname, _) as o = defined_in entrypoint in
1041+
if !explain then
1042+
Printf.printf "%s(%s) because of entrypoint %s\n%!" libname objname
1043+
entrypoint;
1044+
link_libobj o
1045+
with Not_found ->
1046+
if !explain then
1047+
Printf.printf "Entrypoint %s not found\n%!" entrypoint
1048+
in
10021049
let redirect = Hashtbl.create 16 in
10031050
List.iter
10041051
(fun (fn, obj) ->
@@ -1134,24 +1181,24 @@ let build_dll link_exe output_file files exts extra_args =
11341181
being an empty file. *)
11351182
let c = open_out implib in output_string c "x"; close_out c;
11361183
let _impexp = add_temp (Filename.chop_suffix implib ".lib" ^ ".exp") in
1137-
let extra_args =
1138-
if !custom_crt then "/nodefaultlib:LIBCMT /nodefaultlib:MSVCRT " ^ extra_args
1139-
else "msvcrt.lib " ^ extra_args
1184+
let extra_args_string =
1185+
if !custom_crt then "/nodefaultlib:LIBCMT /nodefaultlib:MSVCRT " ^ extra_args_string
1186+
else "msvcrt.lib " ^ extra_args_string
11401187
in
11411188

1142-
let extra_args =
1143-
if !machine = `x64 then (Printf.sprintf "/base:%s " !base_addr) ^ extra_args else extra_args
1189+
let extra_args_string =
1190+
if !machine = `x64 then (Printf.sprintf "/base:%s " !base_addr) ^ extra_args_string else extra_args_string
11441191
in
11451192

1146-
let extra_args =
1193+
let extra_args_string =
11471194
(* FlexDLL doesn't process .voltbl sections correctly, so don't allow the linker
11481195
to process them. *)
11491196
let command =
11501197
if Sys.win32 then link ^ " /nologo /? | findstr EMITVOLATILEMETADATA > NUL"
11511198
else link ^ " /nologo '/?' | grep -iq emitvolatilemetadata >/dev/null" in
11521199
if Sys.command command = 0 then
1153-
"/EMITVOLATILEMETADATA:NO " ^ extra_args
1154-
else extra_args
1200+
"/EMITVOLATILEMETADATA:NO " ^ extra_args_string
1201+
else extra_args_string
11551202
in
11561203

11571204
(* Flexdll requires that all images (main programs and all the DLLs) are
@@ -1179,7 +1226,7 @@ let build_dll link_exe output_file files exts extra_args =
11791226
(Filename.quote output_file)
11801227
!subsystem
11811228
files descr
1182-
extra_args
1229+
extra_args_string
11831230
| `CYGWIN64 ->
11841231
let def_file =
11851232
if main_pgm then ""
@@ -1201,7 +1248,7 @@ let build_dll link_exe output_file files exts extra_args =
12011248
descr
12021249
files
12031250
def_file
1204-
extra_args
1251+
extra_args_string
12051252
| `MINGW | `MINGW64 | `GNAT | `GNAT64 ->
12061253
let def_file =
12071254
if main_pgm then ""
@@ -1225,7 +1272,7 @@ let build_dll link_exe output_file files exts extra_args =
12251272
files
12261273
def_file
12271274
(if !implib then "-Wl,--out-implib=" ^ Filename.quote (Filename.chop_extension output_file ^ ".a") else "")
1228-
extra_args
1275+
extra_args_string
12291276
| `LIGHTLD ->
12301277
no_merge_manifest := true;
12311278
let ld = Option.value !Cmdline.use_linker ~default:"ld" in
@@ -1238,7 +1285,7 @@ let build_dll link_exe output_file files exts extra_args =
12381285
descr
12391286
files
12401287
(if !implib then "--out-implib " ^ Filename.quote (Filename.chop_extension output_file ^ ".a") else "")
1241-
extra_args
1288+
extra_args_string
12421289
in
12431290
debug ~dry_mode 1 "+ %s" cmd;
12441291
if not !dry_mode then begin

0 commit comments

Comments
 (0)