Skip to content

Commit 58db0d1

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 39c90a2 commit 58db0d1

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
@@ -1,8 +1,9 @@
11
Next version
22
- GPR#127: Recognise hyphens in option names in the COFF .drectve section. Fixes #126 (Reza Barazesh)
33
- GPR#136: Fix parallel access crashes and misbehavior (David Allsopp, Jan Midtgaard, Antonin Décimo)
4-
- GPR#146: For mingw-w64, select crt2u.o instead of crt2.o if -link -municode
5-
is specified (David Allsopp)
4+
- GPR#146: Take the entrypoint (main, wmainCRTStartup, etc.) into account when
5+
determining the modules which will be linked. For mingw-w64, select crt2u.o
6+
instead of crt2.o if -link -municode is specified (David Allsopp)
67

78
Version 0.43
89
- 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
@@ -697,7 +697,7 @@ let needed imported defined resolve_alias resolve_alternate obj =
697697
StrSet.empty
698698
obj.symbols
699699

700-
let build_dll link_exe output_file files exts extra_args =
700+
let build_dll link_exe output_file files exts extra_args_string =
701701
let main_pgm = link_exe <> `DLL in
702702

703703
(* fully resolve filenames, eliminate duplicates *)
@@ -979,6 +979,53 @@ let build_dll link_exe output_file files exts extra_args =
979979
link_obj (Printf.sprintf "%s(%s)" libname objname) obj)
980980
in
981981

982+
let entrypoint =
983+
if not main_pgm then
984+
None
985+
else
986+
match !toolchain with
987+
| `CYGWIN64 ->
988+
Some "main"
989+
| `MINGW | `MINGW64 -> begin
990+
let entry_point s =
991+
String.length s > 7 && String.sub s 0 7 = "-Wl,-e,"
992+
in
993+
try
994+
let s = List.find entry_point !extra_args in
995+
Some (String.sub s 7 (String.length s - 7))
996+
with Not_found ->
997+
Some "mainCRTStartup"
998+
end
999+
| `MSVC | `MSVC64 -> begin
1000+
let entry_point s =
1001+
String.length s > 7 && String.lowercase_ascii (String.sub s 0 7) = "/entry:"
1002+
in
1003+
try
1004+
let s = List.find entry_point !extra_args in
1005+
Some (String.sub s 7 (String.length s - 7))
1006+
with Not_found ->
1007+
if !subsystem = "windows" then
1008+
Some "WinMainCRTStartup"
1009+
else
1010+
Some "mainCRTStartup"
1011+
end
1012+
| `LIGHTLD | `GNAT | `GNAT64 ->
1013+
None
1014+
in
1015+
let () =
1016+
match entrypoint with
1017+
| None -> ()
1018+
| Some entrypoint ->
1019+
try
1020+
let (libname, objname, _) as o = defined_in entrypoint in
1021+
if !explain then
1022+
Printf.printf "%s(%s) because of entrypoint %s\n%!" libname objname
1023+
entrypoint;
1024+
link_libobj o
1025+
with Not_found ->
1026+
if !explain then
1027+
Printf.printf "Entrypoint %s not found\n%!" entrypoint
1028+
in
9821029
let redirect = Hashtbl.create 16 in
9831030
List.iter
9841031
(fun (fn, obj) ->
@@ -1113,21 +1160,21 @@ let build_dll link_exe output_file files exts extra_args =
11131160
being an empty file. *)
11141161
let c = open_out implib in output_string c "x"; close_out c;
11151162
let _impexp = add_temp (Filename.chop_suffix implib ".lib" ^ ".exp") in
1116-
let extra_args =
1117-
if !custom_crt then "/nodefaultlib:LIBCMT /nodefaultlib:MSVCRT " ^ extra_args
1118-
else "msvcrt.lib " ^ extra_args
1163+
let extra_args_string =
1164+
if !custom_crt then "/nodefaultlib:LIBCMT /nodefaultlib:MSVCRT " ^ extra_args_string
1165+
else "msvcrt.lib " ^ extra_args_string
11191166
in
11201167

1121-
let extra_args =
1122-
if !machine = `x64 then (Printf.sprintf "/base:%s " !base_addr) ^ extra_args else extra_args
1168+
let extra_args_string =
1169+
if !machine = `x64 then (Printf.sprintf "/base:%s " !base_addr) ^ extra_args_string else extra_args_string
11231170
in
11241171

1125-
let extra_args =
1172+
let extra_args_string =
11261173
(* FlexDLL doesn't process .voltbl sections correctly, so don't allow the linker
11271174
to process them. *)
11281175
if Sys.command "link | findstr EMITVOLATILEMETADATA > nul" = 0 then
1129-
"/EMITVOLATILEMETADATA:NO " ^ extra_args
1130-
else extra_args
1176+
"/EMITVOLATILEMETADATA:NO " ^ extra_args_string
1177+
else extra_args_string
11311178
in
11321179

11331180
(* Flexdll requires that all images (main programs and all the DLLs) are
@@ -1154,7 +1201,7 @@ let build_dll link_exe output_file files exts extra_args =
11541201
(Filename.quote output_file)
11551202
!subsystem
11561203
files descr
1157-
extra_args
1204+
extra_args_string
11581205
| `CYGWIN64 ->
11591206
let def_file =
11601207
if main_pgm then ""
@@ -1175,7 +1222,7 @@ let build_dll link_exe output_file files exts extra_args =
11751222
descr
11761223
files
11771224
def_file
1178-
extra_args
1225+
extra_args_string
11791226
| `MINGW | `MINGW64 | `GNAT | `GNAT64 ->
11801227
let def_file =
11811228
if main_pgm then ""
@@ -1198,7 +1245,7 @@ let build_dll link_exe output_file files exts extra_args =
11981245
files
11991246
def_file
12001247
(if !implib then "-Wl,--out-implib=" ^ Filename.quote (Filename.chop_extension output_file ^ ".a") else "")
1201-
extra_args
1248+
extra_args_string
12021249
| `LIGHTLD ->
12031250
no_merge_manifest := true;
12041251
Printf.sprintf
@@ -1209,7 +1256,7 @@ let build_dll link_exe output_file files exts extra_args =
12091256
descr
12101257
files
12111258
(if !implib then "--out-implib " ^ Filename.quote (Filename.chop_extension output_file ^ ".a") else "")
1212-
extra_args
1259+
extra_args_string
12131260
in
12141261
debug ~dry_mode 1 "+ %s" cmd;
12151262
if not !dry_mode then begin

0 commit comments

Comments
 (0)