2016-02-18 07:11:59 -08:00
|
|
|
/**************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* OCaml */
|
|
|
|
/* */
|
|
|
|
/* Xavier Leroy and Damien Doligez, INRIA Rocquencourt */
|
|
|
|
/* */
|
|
|
|
/* Copyright 1996 Institut National de Recherche en Informatique et */
|
|
|
|
/* en Automatique. */
|
|
|
|
/* */
|
|
|
|
/* All rights reserved. This file is distributed under the terms of */
|
|
|
|
/* the GNU Lesser General Public License version 2.1, with the */
|
|
|
|
/* special exception on linking described in the file LICENSE. */
|
|
|
|
/* */
|
|
|
|
/**************************************************************************/
|
1996-07-24 05:58:12 -07:00
|
|
|
|
2016-07-04 10:00:57 -07:00
|
|
|
#define CAML_INTERNALS
|
|
|
|
|
1996-07-24 05:58:12 -07:00
|
|
|
/* Start-up code */
|
|
|
|
|
2018-12-10 23:54:49 -08:00
|
|
|
#include <errno.h>
|
1996-07-24 05:58:12 -07:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <fcntl.h>
|
2014-12-27 06:41:49 -08:00
|
|
|
#include "caml/config.h"
|
1996-07-24 05:58:12 -07:00
|
|
|
#ifdef HAS_UNISTD
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
2000-04-04 06:19:12 -07:00
|
|
|
#ifdef _WIN32
|
2001-04-10 04:14:33 -07:00
|
|
|
#include <process.h>
|
2000-04-04 06:19:12 -07:00
|
|
|
#endif
|
2014-12-27 06:41:49 -08:00
|
|
|
#include "caml/alloc.h"
|
|
|
|
#include "caml/backtrace.h"
|
|
|
|
#include "caml/callback.h"
|
|
|
|
#include "caml/custom.h"
|
|
|
|
#include "caml/debugger.h"
|
2019-06-03 04:56:45 -07:00
|
|
|
#include "caml/domain.h"
|
2014-12-27 06:41:49 -08:00
|
|
|
#include "caml/dynlink.h"
|
2019-11-15 04:52:35 -08:00
|
|
|
#include "caml/eventlog.h"
|
2014-12-27 06:41:49 -08:00
|
|
|
#include "caml/exec.h"
|
|
|
|
#include "caml/fail.h"
|
|
|
|
#include "caml/fix_code.h"
|
|
|
|
#include "caml/freelist.h"
|
|
|
|
#include "caml/gc_ctrl.h"
|
|
|
|
#include "caml/instrtrace.h"
|
|
|
|
#include "caml/interp.h"
|
|
|
|
#include "caml/intext.h"
|
|
|
|
#include "caml/io.h"
|
|
|
|
#include "caml/memory.h"
|
|
|
|
#include "caml/minor_gc.h"
|
|
|
|
#include "caml/misc.h"
|
|
|
|
#include "caml/mlvalues.h"
|
|
|
|
#include "caml/osdeps.h"
|
|
|
|
#include "caml/prims.h"
|
|
|
|
#include "caml/printexc.h"
|
|
|
|
#include "caml/reverse.h"
|
|
|
|
#include "caml/signals.h"
|
|
|
|
#include "caml/stacks.h"
|
|
|
|
#include "caml/sys.h"
|
|
|
|
#include "caml/startup.h"
|
2015-05-04 08:44:40 -07:00
|
|
|
#include "caml/startup_aux.h"
|
2014-12-27 06:41:49 -08:00
|
|
|
#include "caml/version.h"
|
1996-07-24 05:58:12 -07:00
|
|
|
|
|
|
|
#ifndef O_BINARY
|
|
|
|
#define O_BINARY 0
|
|
|
|
#endif
|
|
|
|
|
1997-06-13 08:49:36 -07:00
|
|
|
#ifndef SEEK_END
|
|
|
|
#define SEEK_END 2
|
|
|
|
#endif
|
|
|
|
|
2018-05-15 06:15:06 -07:00
|
|
|
static char magicstr[EXEC_MAGIC_LENGTH+1];
|
2018-05-17 05:20:00 -07:00
|
|
|
static int print_magic = 0;
|
2018-05-15 06:15:06 -07:00
|
|
|
|
2019-10-18 15:15:51 -07:00
|
|
|
/* Print the specified error message followed by an end-of-line and exit */
|
|
|
|
static void error(char *msg, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, msg);
|
|
|
|
vfprintf (stderr, msg, ap);
|
|
|
|
va_end(ap);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
exit(127);
|
|
|
|
}
|
|
|
|
|
1996-11-07 02:57:59 -08:00
|
|
|
/* Read the trailer of a bytecode file */
|
|
|
|
|
2014-08-27 02:58:33 -07:00
|
|
|
static void fixup_endianness_trailer(uint32_t * p)
|
1996-07-24 05:58:12 -07:00
|
|
|
{
|
2000-03-05 11:18:50 -08:00
|
|
|
#ifndef ARCH_BIG_ENDIAN
|
|
|
|
Reverse_32(p, p);
|
|
|
|
#endif
|
|
|
|
}
|
1996-07-24 05:58:12 -07:00
|
|
|
|
2000-03-05 11:18:50 -08:00
|
|
|
static int read_trailer(int fd, struct exec_trailer *trail)
|
|
|
|
{
|
2013-08-01 02:19:05 -07:00
|
|
|
if (lseek(fd, (long) -TRAILER_SIZE, SEEK_END) == -1)
|
|
|
|
return BAD_BYTECODE;
|
2000-03-05 11:18:50 -08:00
|
|
|
if (read(fd, (char *) trail, TRAILER_SIZE) < TRAILER_SIZE)
|
2001-02-19 02:01:41 -08:00
|
|
|
return BAD_BYTECODE;
|
2000-03-05 11:18:50 -08:00
|
|
|
fixup_endianness_trailer(&trail->num_sections);
|
2018-05-17 05:20:00 -07:00
|
|
|
memcpy(magicstr, trail->magic, EXEC_MAGIC_LENGTH);
|
|
|
|
magicstr[EXEC_MAGIC_LENGTH] = 0;
|
2017-08-12 13:24:41 -07:00
|
|
|
|
2018-05-17 05:20:00 -07:00
|
|
|
if (print_magic) {
|
|
|
|
printf("%s\n", magicstr);
|
|
|
|
exit(0);
|
2018-05-15 06:15:06 -07:00
|
|
|
}
|
2018-05-17 05:20:00 -07:00
|
|
|
return
|
|
|
|
(strncmp(trail->magic, EXEC_MAGIC, sizeof(trail->magic)) == 0)
|
|
|
|
? 0 : WRONG_MAGIC;
|
1996-07-24 05:58:12 -07:00
|
|
|
}
|
|
|
|
|
2020-03-17 04:38:45 -07:00
|
|
|
enum caml_byte_program_mode caml_byte_program_mode = STANDARD;
|
|
|
|
|
2017-09-21 03:29:03 -07:00
|
|
|
int caml_attempt_open(char_os **name, struct exec_trailer *trail,
|
2003-12-31 06:20:40 -08:00
|
|
|
int do_open_script)
|
1996-07-24 05:58:12 -07:00
|
|
|
{
|
2017-09-21 03:29:03 -07:00
|
|
|
char_os * truename;
|
1996-07-24 05:58:12 -07:00
|
|
|
int fd;
|
|
|
|
int err;
|
2017-10-04 07:23:29 -07:00
|
|
|
char buf [2], * u8;
|
1996-07-24 05:58:12 -07:00
|
|
|
|
2004-01-01 08:42:43 -08:00
|
|
|
truename = caml_search_exe_in_path(*name);
|
2017-10-04 07:23:29 -07:00
|
|
|
u8 = caml_stat_strdup_of_os(truename);
|
|
|
|
caml_gc_message(0x100, "Opening bytecode executable %s\n", u8);
|
|
|
|
caml_stat_free(u8);
|
2017-09-21 03:29:03 -07:00
|
|
|
fd = open_os(truename, O_RDONLY | O_BINARY);
|
2001-02-19 02:01:41 -08:00
|
|
|
if (fd == -1) {
|
2016-09-04 23:49:25 -07:00
|
|
|
caml_stat_free(truename);
|
2017-02-27 08:32:44 -08:00
|
|
|
caml_gc_message(0x100, "Cannot open file\n");
|
2018-12-10 23:54:49 -08:00
|
|
|
if (errno == EMFILE)
|
|
|
|
return NO_FDS;
|
|
|
|
else
|
|
|
|
return FILE_NOT_FOUND;
|
2001-02-19 02:01:41 -08:00
|
|
|
}
|
|
|
|
if (!do_open_script) {
|
1996-07-24 05:58:12 -07:00
|
|
|
err = read (fd, buf, 2);
|
2001-02-19 02:01:41 -08:00
|
|
|
if (err < 2 || (buf [0] == '#' && buf [1] == '!')) {
|
|
|
|
close(fd);
|
2016-09-04 23:49:25 -07:00
|
|
|
caml_stat_free(truename);
|
2017-02-27 08:32:44 -08:00
|
|
|
caml_gc_message(0x100, "Rejected #! script\n");
|
2001-02-19 02:01:41 -08:00
|
|
|
return BAD_BYTECODE;
|
|
|
|
}
|
1996-07-24 05:58:12 -07:00
|
|
|
}
|
|
|
|
err = read_trailer(fd, trail);
|
2001-02-19 02:01:41 -08:00
|
|
|
if (err != 0) {
|
|
|
|
close(fd);
|
2016-09-04 23:49:25 -07:00
|
|
|
caml_stat_free(truename);
|
2017-02-27 08:32:44 -08:00
|
|
|
caml_gc_message(0x100, "Not a bytecode executable\n");
|
2001-02-19 02:01:41 -08:00
|
|
|
return err;
|
|
|
|
}
|
2016-09-04 23:49:25 -07:00
|
|
|
*name = truename;
|
1996-07-24 05:58:12 -07:00
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
2000-03-05 11:18:50 -08:00
|
|
|
/* Read the section descriptors */
|
|
|
|
|
2003-12-31 06:20:40 -08:00
|
|
|
void caml_read_section_descriptors(int fd, struct exec_trailer *trail)
|
2000-03-05 11:18:50 -08:00
|
|
|
{
|
|
|
|
int toc_size, i;
|
|
|
|
|
|
|
|
toc_size = trail->num_sections * 8;
|
2003-12-31 06:20:40 -08:00
|
|
|
trail->section = caml_stat_alloc(toc_size);
|
2000-03-05 11:18:50 -08:00
|
|
|
lseek(fd, - (long) (TRAILER_SIZE + toc_size), SEEK_END);
|
|
|
|
if (read(fd, (char *) trail->section, toc_size) != toc_size)
|
2018-05-17 06:17:04 -07:00
|
|
|
caml_fatal_error("cannot read section table");
|
2000-03-05 11:18:50 -08:00
|
|
|
/* Fixup endianness of lengths */
|
|
|
|
for (i = 0; i < trail->num_sections; i++)
|
|
|
|
fixup_endianness_trailer(&(trail->section[i].len));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Position fd at the beginning of the section having the given name.
|
2001-02-19 04:29:00 -08:00
|
|
|
Return the length of the section data in bytes, or -1 if no section
|
|
|
|
found with that name. */
|
2000-03-05 11:18:50 -08:00
|
|
|
|
2015-09-11 04:58:31 -07:00
|
|
|
int32_t caml_seek_optional_section(int fd, struct exec_trailer *trail,
|
|
|
|
char *name)
|
2000-03-05 11:18:50 -08:00
|
|
|
{
|
|
|
|
long ofs;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ofs = TRAILER_SIZE + trail->num_sections * 8;
|
|
|
|
for (i = trail->num_sections - 1; i >= 0; i--) {
|
|
|
|
ofs += trail->section[i].len;
|
|
|
|
if (strncmp(trail->section[i].name, name, 4) == 0) {
|
|
|
|
lseek(fd, -ofs, SEEK_END);
|
|
|
|
return trail->section[i].len;
|
|
|
|
}
|
|
|
|
}
|
2001-02-19 04:29:00 -08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Position fd at the beginning of the section having the given name.
|
|
|
|
Return the length of the section data in bytes. */
|
|
|
|
|
2014-08-27 02:58:33 -07:00
|
|
|
int32_t caml_seek_section(int fd, struct exec_trailer *trail, char *name)
|
2001-02-19 04:29:00 -08:00
|
|
|
{
|
2014-08-27 02:58:33 -07:00
|
|
|
int32_t len = caml_seek_optional_section(fd, trail, name);
|
2010-01-22 04:48:24 -08:00
|
|
|
if (len == -1)
|
2018-05-17 23:28:19 -07:00
|
|
|
caml_fatal_error("section `%s' is missing", name);
|
2001-02-19 04:29:00 -08:00
|
|
|
return len;
|
2000-03-05 11:18:50 -08:00
|
|
|
}
|
|
|
|
|
2001-08-28 07:47:48 -07:00
|
|
|
/* Read and return the contents of the section having the given name.
|
|
|
|
Add a terminating 0. Return NULL if no such section. */
|
1997-06-13 08:49:36 -07:00
|
|
|
|
2001-08-28 07:47:48 -07:00
|
|
|
static char * read_section(int fd, struct exec_trailer *trail, char *name)
|
1997-06-13 08:49:36 -07:00
|
|
|
{
|
2014-08-27 02:58:33 -07:00
|
|
|
int32_t len;
|
2001-08-28 07:47:48 -07:00
|
|
|
char * data;
|
|
|
|
|
2003-12-31 06:20:40 -08:00
|
|
|
len = caml_seek_optional_section(fd, trail, name);
|
2001-08-28 07:47:48 -07:00
|
|
|
if (len == -1) return NULL;
|
2003-12-31 06:20:40 -08:00
|
|
|
data = caml_stat_alloc(len + 1);
|
2001-08-28 07:47:48 -07:00
|
|
|
if (read(fd, data, len) != len)
|
2018-05-17 23:28:19 -07:00
|
|
|
caml_fatal_error("error reading section %s", name);
|
2001-08-28 07:47:48 -07:00
|
|
|
data[len] = 0;
|
|
|
|
return data;
|
1997-06-13 08:49:36 -07:00
|
|
|
}
|
|
|
|
|
Unicode support for the Windows runtime (#1200)
* Add support code
* Explicitly reference ANSI Windows APIs
* Adapt Sys.is_directory
* Adapt ocamlrun
* Add Changes entry
* Add testsuite
* Adapt Unix.open_process{_in,_out,_full,}, Unix.create_process{_env,}
* Adapt headernt.c
* Adapt Pervasives.open_{in,out}, Filename.temp_file, etc.
* Adapt Sys.file_exists
* Adapt Sys.remove
* Adapt Sys.chdir
* Adapt Sys.getcwd
* Adapt Sys.getenv
* Adapt Sys.command
* Adapt Sys.readdir
* Adapt CPLUGINS
* Remove use of FormatMessageA, CreateFileA
* Adapt Unix.mkdir
* Adapt Unix.openfile
* Adapt Unix.readlink
* Adapt Unix.rename
* Adapt Unix.{LargeFile,}.{l,}stat
* Adapt Unix.system
* Adapt Unix.{open,read}dir
* Adapt Unix.link
* Adapt Unix.symlink
* Adapt Unix.getcwd
* Adapt Unix.rmdir
* Adapt Unix.utimes
* Adapt Unix.unlink
* Adapt Unix.chdir
* Adapt Unix.chmod
* Adapt Unix.{execv,execve,execvp,execvpe}
* Compile with -DUNICODE -D_UNICODE under Windows
* Add configure-time switch, Config.windows_unicode
* Adapt Unix.putenv
* Re-implement Unix.environment using GetEnvironmentStrings()
* Use Unicode-aware flexdll
* Adapt Unix.environment
* AppVeyor: bootstrap flexdll
* Adapt tests/embedded/cmmain.c
* Adapt tests/lib-dynlink-csharp/entry.c
* Remove exec tests
* Fixup
* Pass -municode to MinGW compiler
* Try to fix tests/embedded
* Adapt Sys.rename
* Correct Changes entry
* Makefile.several: use $(O) and $(NATIVECODE_ONLY)
* Display => skipped correctly for tests/win-unicode
* Add missing casts to execv* calls
It's not clear why these aren't necessary for with char, but they are
necessary with wchar_t on GCC (but not MSVC).
* Missing header in systhreads (Win32 only)
* Revert "Pass -municode to MinGW compiler"
This reverts commit a4ce7fb319c429068a5b9d1ab14a2cc3969c355f.
* Revert "Try to fix tests/embedded"
This reverts commit 5197d8922295b7b339b970ec3189374aa15de4b8.
* Revert "Remove exec tests"
This reverts commit 306ccef2e79eca5b38ecfa285b912c7bcf3e9f52.
* Don't pass $(LDFLAGS) when build ocamlc.opt
It's already included via CC anyway, and it causes Unicode problems for
Winodws (because the linker options need to be prefixed "-link" to go via
flexlink).
* Use wmain on Windows for ocamlrun
* Build Unicode applications on Windows
* Use wmain in headernt.c
* Minor correction to win-unicode Makefile
* Switch submodule to FlexDLL 0.36
* Build ocamlyacc as an ANSI application
* Revert "Fixup"
This reverts commit 500bd6b575ffd6c5b71c6953e55d740f0b090185.
* Fix casts for execvp/execve
* Remove tabs from test code
* Fix Changes entry
* shell32.lib is no longer necessary
* Free allocated string
* Changes: signal breaking change
* Disable exec_tests
* Protect with CAML_INTERNALS
2017-09-18 08:41:29 -07:00
|
|
|
#ifdef _WIN32
|
|
|
|
|
2017-08-12 13:24:41 -07:00
|
|
|
static char_os * read_section_to_os(int fd, struct exec_trailer *trail,
|
|
|
|
char *name)
|
Unicode support for the Windows runtime (#1200)
* Add support code
* Explicitly reference ANSI Windows APIs
* Adapt Sys.is_directory
* Adapt ocamlrun
* Add Changes entry
* Add testsuite
* Adapt Unix.open_process{_in,_out,_full,}, Unix.create_process{_env,}
* Adapt headernt.c
* Adapt Pervasives.open_{in,out}, Filename.temp_file, etc.
* Adapt Sys.file_exists
* Adapt Sys.remove
* Adapt Sys.chdir
* Adapt Sys.getcwd
* Adapt Sys.getenv
* Adapt Sys.command
* Adapt Sys.readdir
* Adapt CPLUGINS
* Remove use of FormatMessageA, CreateFileA
* Adapt Unix.mkdir
* Adapt Unix.openfile
* Adapt Unix.readlink
* Adapt Unix.rename
* Adapt Unix.{LargeFile,}.{l,}stat
* Adapt Unix.system
* Adapt Unix.{open,read}dir
* Adapt Unix.link
* Adapt Unix.symlink
* Adapt Unix.getcwd
* Adapt Unix.rmdir
* Adapt Unix.utimes
* Adapt Unix.unlink
* Adapt Unix.chdir
* Adapt Unix.chmod
* Adapt Unix.{execv,execve,execvp,execvpe}
* Compile with -DUNICODE -D_UNICODE under Windows
* Add configure-time switch, Config.windows_unicode
* Adapt Unix.putenv
* Re-implement Unix.environment using GetEnvironmentStrings()
* Use Unicode-aware flexdll
* Adapt Unix.environment
* AppVeyor: bootstrap flexdll
* Adapt tests/embedded/cmmain.c
* Adapt tests/lib-dynlink-csharp/entry.c
* Remove exec tests
* Fixup
* Pass -municode to MinGW compiler
* Try to fix tests/embedded
* Adapt Sys.rename
* Correct Changes entry
* Makefile.several: use $(O) and $(NATIVECODE_ONLY)
* Display => skipped correctly for tests/win-unicode
* Add missing casts to execv* calls
It's not clear why these aren't necessary for with char, but they are
necessary with wchar_t on GCC (but not MSVC).
* Missing header in systhreads (Win32 only)
* Revert "Pass -municode to MinGW compiler"
This reverts commit a4ce7fb319c429068a5b9d1ab14a2cc3969c355f.
* Revert "Try to fix tests/embedded"
This reverts commit 5197d8922295b7b339b970ec3189374aa15de4b8.
* Revert "Remove exec tests"
This reverts commit 306ccef2e79eca5b38ecfa285b912c7bcf3e9f52.
* Don't pass $(LDFLAGS) when build ocamlc.opt
It's already included via CC anyway, and it causes Unicode problems for
Winodws (because the linker options need to be prefixed "-link" to go via
flexlink).
* Use wmain on Windows for ocamlrun
* Build Unicode applications on Windows
* Use wmain in headernt.c
* Minor correction to win-unicode Makefile
* Switch submodule to FlexDLL 0.36
* Build ocamlyacc as an ANSI application
* Revert "Fixup"
This reverts commit 500bd6b575ffd6c5b71c6953e55d740f0b090185.
* Fix casts for execvp/execve
* Remove tabs from test code
* Fix Changes entry
* shell32.lib is no longer necessary
* Free allocated string
* Changes: signal breaking change
* Disable exec_tests
* Protect with CAML_INTERNALS
2017-09-18 08:41:29 -07:00
|
|
|
{
|
|
|
|
int32_t len, wlen;
|
|
|
|
char * data;
|
|
|
|
wchar_t * wdata;
|
|
|
|
|
|
|
|
len = caml_seek_optional_section(fd, trail, name);
|
|
|
|
if (len == -1) return NULL;
|
|
|
|
data = caml_stat_alloc(len + 1);
|
|
|
|
if (read(fd, data, len) != len)
|
2018-05-17 23:28:19 -07:00
|
|
|
caml_fatal_error("error reading section %s", name);
|
Unicode support for the Windows runtime (#1200)
* Add support code
* Explicitly reference ANSI Windows APIs
* Adapt Sys.is_directory
* Adapt ocamlrun
* Add Changes entry
* Add testsuite
* Adapt Unix.open_process{_in,_out,_full,}, Unix.create_process{_env,}
* Adapt headernt.c
* Adapt Pervasives.open_{in,out}, Filename.temp_file, etc.
* Adapt Sys.file_exists
* Adapt Sys.remove
* Adapt Sys.chdir
* Adapt Sys.getcwd
* Adapt Sys.getenv
* Adapt Sys.command
* Adapt Sys.readdir
* Adapt CPLUGINS
* Remove use of FormatMessageA, CreateFileA
* Adapt Unix.mkdir
* Adapt Unix.openfile
* Adapt Unix.readlink
* Adapt Unix.rename
* Adapt Unix.{LargeFile,}.{l,}stat
* Adapt Unix.system
* Adapt Unix.{open,read}dir
* Adapt Unix.link
* Adapt Unix.symlink
* Adapt Unix.getcwd
* Adapt Unix.rmdir
* Adapt Unix.utimes
* Adapt Unix.unlink
* Adapt Unix.chdir
* Adapt Unix.chmod
* Adapt Unix.{execv,execve,execvp,execvpe}
* Compile with -DUNICODE -D_UNICODE under Windows
* Add configure-time switch, Config.windows_unicode
* Adapt Unix.putenv
* Re-implement Unix.environment using GetEnvironmentStrings()
* Use Unicode-aware flexdll
* Adapt Unix.environment
* AppVeyor: bootstrap flexdll
* Adapt tests/embedded/cmmain.c
* Adapt tests/lib-dynlink-csharp/entry.c
* Remove exec tests
* Fixup
* Pass -municode to MinGW compiler
* Try to fix tests/embedded
* Adapt Sys.rename
* Correct Changes entry
* Makefile.several: use $(O) and $(NATIVECODE_ONLY)
* Display => skipped correctly for tests/win-unicode
* Add missing casts to execv* calls
It's not clear why these aren't necessary for with char, but they are
necessary with wchar_t on GCC (but not MSVC).
* Missing header in systhreads (Win32 only)
* Revert "Pass -municode to MinGW compiler"
This reverts commit a4ce7fb319c429068a5b9d1ab14a2cc3969c355f.
* Revert "Try to fix tests/embedded"
This reverts commit 5197d8922295b7b339b970ec3189374aa15de4b8.
* Revert "Remove exec tests"
This reverts commit 306ccef2e79eca5b38ecfa285b912c7bcf3e9f52.
* Don't pass $(LDFLAGS) when build ocamlc.opt
It's already included via CC anyway, and it causes Unicode problems for
Winodws (because the linker options need to be prefixed "-link" to go via
flexlink).
* Use wmain on Windows for ocamlrun
* Build Unicode applications on Windows
* Use wmain in headernt.c
* Minor correction to win-unicode Makefile
* Switch submodule to FlexDLL 0.36
* Build ocamlyacc as an ANSI application
* Revert "Fixup"
This reverts commit 500bd6b575ffd6c5b71c6953e55d740f0b090185.
* Fix casts for execvp/execve
* Remove tabs from test code
* Fix Changes entry
* shell32.lib is no longer necessary
* Free allocated string
* Changes: signal breaking change
* Disable exec_tests
* Protect with CAML_INTERNALS
2017-09-18 08:41:29 -07:00
|
|
|
data[len] = 0;
|
|
|
|
wlen = win_multi_byte_to_wide_char(data, len, NULL, 0);
|
|
|
|
wdata = caml_stat_alloc((wlen + 1)*sizeof(wchar_t));
|
|
|
|
win_multi_byte_to_wide_char(data, len, wdata, wlen);
|
|
|
|
wdata[wlen] = 0;
|
|
|
|
caml_stat_free(data);
|
|
|
|
return wdata;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2017-09-21 03:29:03 -07:00
|
|
|
#define read_section_to_os read_section
|
Unicode support for the Windows runtime (#1200)
* Add support code
* Explicitly reference ANSI Windows APIs
* Adapt Sys.is_directory
* Adapt ocamlrun
* Add Changes entry
* Add testsuite
* Adapt Unix.open_process{_in,_out,_full,}, Unix.create_process{_env,}
* Adapt headernt.c
* Adapt Pervasives.open_{in,out}, Filename.temp_file, etc.
* Adapt Sys.file_exists
* Adapt Sys.remove
* Adapt Sys.chdir
* Adapt Sys.getcwd
* Adapt Sys.getenv
* Adapt Sys.command
* Adapt Sys.readdir
* Adapt CPLUGINS
* Remove use of FormatMessageA, CreateFileA
* Adapt Unix.mkdir
* Adapt Unix.openfile
* Adapt Unix.readlink
* Adapt Unix.rename
* Adapt Unix.{LargeFile,}.{l,}stat
* Adapt Unix.system
* Adapt Unix.{open,read}dir
* Adapt Unix.link
* Adapt Unix.symlink
* Adapt Unix.getcwd
* Adapt Unix.rmdir
* Adapt Unix.utimes
* Adapt Unix.unlink
* Adapt Unix.chdir
* Adapt Unix.chmod
* Adapt Unix.{execv,execve,execvp,execvpe}
* Compile with -DUNICODE -D_UNICODE under Windows
* Add configure-time switch, Config.windows_unicode
* Adapt Unix.putenv
* Re-implement Unix.environment using GetEnvironmentStrings()
* Use Unicode-aware flexdll
* Adapt Unix.environment
* AppVeyor: bootstrap flexdll
* Adapt tests/embedded/cmmain.c
* Adapt tests/lib-dynlink-csharp/entry.c
* Remove exec tests
* Fixup
* Pass -municode to MinGW compiler
* Try to fix tests/embedded
* Adapt Sys.rename
* Correct Changes entry
* Makefile.several: use $(O) and $(NATIVECODE_ONLY)
* Display => skipped correctly for tests/win-unicode
* Add missing casts to execv* calls
It's not clear why these aren't necessary for with char, but they are
necessary with wchar_t on GCC (but not MSVC).
* Missing header in systhreads (Win32 only)
* Revert "Pass -municode to MinGW compiler"
This reverts commit a4ce7fb319c429068a5b9d1ab14a2cc3969c355f.
* Revert "Try to fix tests/embedded"
This reverts commit 5197d8922295b7b339b970ec3189374aa15de4b8.
* Revert "Remove exec tests"
This reverts commit 306ccef2e79eca5b38ecfa285b912c7bcf3e9f52.
* Don't pass $(LDFLAGS) when build ocamlc.opt
It's already included via CC anyway, and it causes Unicode problems for
Winodws (because the linker options need to be prefixed "-link" to go via
flexlink).
* Use wmain on Windows for ocamlrun
* Build Unicode applications on Windows
* Use wmain in headernt.c
* Minor correction to win-unicode Makefile
* Switch submodule to FlexDLL 0.36
* Build ocamlyacc as an ANSI application
* Revert "Fixup"
This reverts commit 500bd6b575ffd6c5b71c6953e55d740f0b090185.
* Fix casts for execvp/execve
* Remove tabs from test code
* Fix Changes entry
* shell32.lib is no longer necessary
* Free allocated string
* Changes: signal breaking change
* Disable exec_tests
* Protect with CAML_INTERNALS
2017-09-18 08:41:29 -07:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
1998-10-02 06:02:32 -07:00
|
|
|
/* Invocation of ocamlrun: 4 cases.
|
1996-07-24 05:58:12 -07:00
|
|
|
|
|
|
|
1. runtime + bytecode
|
1998-10-02 06:02:32 -07:00
|
|
|
user types: ocamlrun [options] bytecode args...
|
|
|
|
arguments: ocamlrun [options] bytecode args...
|
1996-07-24 05:58:12 -07:00
|
|
|
|
|
|
|
2. bytecode script
|
|
|
|
user types: bytecode args...
|
1998-10-02 06:02:32 -07:00
|
|
|
2a (kernel 1) arguments: ocamlrun ./bytecode args...
|
1996-07-24 05:58:12 -07:00
|
|
|
2b (kernel 2) arguments: bytecode bytecode args...
|
|
|
|
|
|
|
|
3. concatenated runtime and bytecode
|
|
|
|
user types: composite args...
|
|
|
|
arguments: composite args...
|
|
|
|
|
|
|
|
Algorithm:
|
|
|
|
1- If argument 0 is a valid byte-code file that does not start with #!,
|
|
|
|
then we are in case 3 and we pass the same command line to the
|
2011-07-27 07:17:02 -07:00
|
|
|
OCaml program.
|
1996-07-24 05:58:12 -07:00
|
|
|
2- In all other cases, we parse the command line as:
|
|
|
|
(whatever) [options] bytecode args...
|
|
|
|
and we strip "(whatever) [options]" from the command line.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
1996-11-07 02:57:59 -08:00
|
|
|
/* Parse options on the command line */
|
|
|
|
|
2017-09-21 03:29:03 -07:00
|
|
|
static int parse_command_line(char_os **argv)
|
1996-11-07 02:57:59 -08:00
|
|
|
{
|
1998-04-14 07:48:34 -07:00
|
|
|
int i, j;
|
1996-11-07 02:57:59 -08:00
|
|
|
|
2019-04-14 00:13:24 -07:00
|
|
|
for(i = 1; argv[i] != NULL && argv[i][0] == '-'; i++) {
|
1996-11-07 02:57:59 -08:00
|
|
|
switch(argv[i][1]) {
|
2019-04-14 00:13:24 -07:00
|
|
|
case 't':
|
2015-05-04 08:44:40 -07:00
|
|
|
++ caml_trace_level; /* ignored unless DEBUG mode */
|
1996-11-07 02:57:59 -08:00
|
|
|
break;
|
2019-04-14 00:13:24 -07:00
|
|
|
case 'v':
|
|
|
|
if (!strcmp_os (argv[i], T("-version"))){
|
2018-05-25 05:47:47 -07:00
|
|
|
printf ("%s\n", "The OCaml runtime, version " OCAML_VERSION_STRING);
|
2004-11-26 17:04:19 -08:00
|
|
|
exit (0);
|
2019-04-14 00:13:24 -07:00
|
|
|
}else if (!strcmp_os (argv[i], T("-vnum"))){
|
2018-05-25 05:47:47 -07:00
|
|
|
printf ("%s\n", OCAML_VERSION_STRING);
|
2010-05-20 07:06:29 -07:00
|
|
|
exit (0);
|
2004-11-26 17:04:19 -08:00
|
|
|
}else{
|
|
|
|
caml_verb_gc = 0x001+0x004+0x008+0x010+0x020;
|
|
|
|
}
|
1996-11-07 02:57:59 -08:00
|
|
|
break;
|
2019-04-14 00:13:24 -07:00
|
|
|
case 'p':
|
2004-01-01 08:42:43 -08:00
|
|
|
for (j = 0; caml_names_of_builtin_cprim[j] != NULL; j++)
|
|
|
|
printf("%s\n", caml_names_of_builtin_cprim[j]);
|
1998-04-14 07:48:34 -07:00
|
|
|
exit(0);
|
|
|
|
break;
|
2019-04-14 00:13:24 -07:00
|
|
|
case 'b':
|
2008-03-14 06:47:24 -07:00
|
|
|
caml_record_backtrace(Val_true);
|
2001-02-19 04:29:00 -08:00
|
|
|
break;
|
2019-04-14 00:13:24 -07:00
|
|
|
case 'I':
|
2001-08-28 07:47:48 -07:00
|
|
|
if (argv[i + 1] != NULL) {
|
2004-01-01 08:42:43 -08:00
|
|
|
caml_ext_table_add(&caml_shared_libs_path, argv[i + 1]);
|
2001-08-28 07:47:48 -07:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
break;
|
2019-04-14 00:13:24 -07:00
|
|
|
case 'm':
|
2018-05-17 05:20:00 -07:00
|
|
|
print_magic = 1;
|
|
|
|
break;
|
2019-04-14 00:13:24 -07:00
|
|
|
case 'M':
|
2018-05-17 05:20:00 -07:00
|
|
|
printf ( "%s\n", EXEC_MAGIC);
|
|
|
|
exit(0);
|
|
|
|
break;
|
1996-11-07 02:57:59 -08:00
|
|
|
default:
|
2019-10-18 15:15:51 -07:00
|
|
|
error("unknown option %s", caml_stat_strdup_of_os(argv[i]));
|
1996-11-07 02:57:59 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2000-01-31 21:41:23 -08:00
|
|
|
#ifdef _WIN32
|
2001-04-10 04:14:33 -07:00
|
|
|
extern void caml_signal_thread(void * lpParam);
|
2000-01-31 21:41:23 -08:00
|
|
|
#endif
|
|
|
|
|
2015-12-30 12:24:10 -08:00
|
|
|
#if defined(_MSC_VER) && __STDC_SECURE_LIB__ >= 200411L
|
2013-03-09 14:38:52 -08:00
|
|
|
|
2013-01-17 01:04:53 -08:00
|
|
|
/* PR 4887: avoid crash box of windows runtime on some system calls */
|
|
|
|
extern void caml_install_invalid_parameter_handler();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
1996-11-07 02:57:59 -08:00
|
|
|
/* Main entry point when loading code from a file */
|
1996-07-24 05:58:12 -07:00
|
|
|
|
2017-09-21 03:29:03 -07:00
|
|
|
CAMLexport void caml_main(char_os **argv)
|
1996-07-24 05:58:12 -07:00
|
|
|
{
|
2000-03-05 11:18:50 -08:00
|
|
|
int fd, pos;
|
1996-07-24 05:58:12 -07:00
|
|
|
struct exec_trailer trail;
|
2015-12-08 05:33:20 -08:00
|
|
|
struct channel * chan;
|
1999-02-14 08:48:25 -08:00
|
|
|
value res;
|
Unicode support for the Windows runtime (#1200)
* Add support code
* Explicitly reference ANSI Windows APIs
* Adapt Sys.is_directory
* Adapt ocamlrun
* Add Changes entry
* Add testsuite
* Adapt Unix.open_process{_in,_out,_full,}, Unix.create_process{_env,}
* Adapt headernt.c
* Adapt Pervasives.open_{in,out}, Filename.temp_file, etc.
* Adapt Sys.file_exists
* Adapt Sys.remove
* Adapt Sys.chdir
* Adapt Sys.getcwd
* Adapt Sys.getenv
* Adapt Sys.command
* Adapt Sys.readdir
* Adapt CPLUGINS
* Remove use of FormatMessageA, CreateFileA
* Adapt Unix.mkdir
* Adapt Unix.openfile
* Adapt Unix.readlink
* Adapt Unix.rename
* Adapt Unix.{LargeFile,}.{l,}stat
* Adapt Unix.system
* Adapt Unix.{open,read}dir
* Adapt Unix.link
* Adapt Unix.symlink
* Adapt Unix.getcwd
* Adapt Unix.rmdir
* Adapt Unix.utimes
* Adapt Unix.unlink
* Adapt Unix.chdir
* Adapt Unix.chmod
* Adapt Unix.{execv,execve,execvp,execvpe}
* Compile with -DUNICODE -D_UNICODE under Windows
* Add configure-time switch, Config.windows_unicode
* Adapt Unix.putenv
* Re-implement Unix.environment using GetEnvironmentStrings()
* Use Unicode-aware flexdll
* Adapt Unix.environment
* AppVeyor: bootstrap flexdll
* Adapt tests/embedded/cmmain.c
* Adapt tests/lib-dynlink-csharp/entry.c
* Remove exec tests
* Fixup
* Pass -municode to MinGW compiler
* Try to fix tests/embedded
* Adapt Sys.rename
* Correct Changes entry
* Makefile.several: use $(O) and $(NATIVECODE_ONLY)
* Display => skipped correctly for tests/win-unicode
* Add missing casts to execv* calls
It's not clear why these aren't necessary for with char, but they are
necessary with wchar_t on GCC (but not MSVC).
* Missing header in systhreads (Win32 only)
* Revert "Pass -municode to MinGW compiler"
This reverts commit a4ce7fb319c429068a5b9d1ab14a2cc3969c355f.
* Revert "Try to fix tests/embedded"
This reverts commit 5197d8922295b7b339b970ec3189374aa15de4b8.
* Revert "Remove exec tests"
This reverts commit 306ccef2e79eca5b38ecfa285b912c7bcf3e9f52.
* Don't pass $(LDFLAGS) when build ocamlc.opt
It's already included via CC anyway, and it causes Unicode problems for
Winodws (because the linker options need to be prefixed "-link" to go via
flexlink).
* Use wmain on Windows for ocamlrun
* Build Unicode applications on Windows
* Use wmain in headernt.c
* Minor correction to win-unicode Makefile
* Switch submodule to FlexDLL 0.36
* Build ocamlyacc as an ANSI application
* Revert "Fixup"
This reverts commit 500bd6b575ffd6c5b71c6953e55d740f0b090185.
* Fix casts for execvp/execve
* Remove tabs from test code
* Fix Changes entry
* shell32.lib is no longer necessary
* Free allocated string
* Changes: signal breaking change
* Disable exec_tests
* Protect with CAML_INTERNALS
2017-09-18 08:41:29 -07:00
|
|
|
char * req_prims;
|
2017-09-21 03:29:03 -07:00
|
|
|
char_os * shared_lib_path, * shared_libs;
|
|
|
|
char_os * exe_name, * proc_self_exe;
|
1996-07-24 05:58:12 -07:00
|
|
|
|
2019-06-17 22:47:26 -07:00
|
|
|
/* Initialize the domain */
|
|
|
|
caml_init_domain();
|
|
|
|
|
2016-11-13 14:31:58 -08:00
|
|
|
/* Determine options */
|
|
|
|
#ifdef DEBUG
|
|
|
|
caml_verb_gc = 0x3F;
|
|
|
|
#endif
|
|
|
|
caml_parse_ocamlrunparam();
|
2019-11-15 04:52:35 -08:00
|
|
|
CAML_EVENTLOG_INIT();
|
2016-11-13 14:31:58 -08:00
|
|
|
#ifdef DEBUG
|
2017-02-27 08:32:44 -08:00
|
|
|
caml_gc_message (-1, "### OCaml runtime: debug mode ###\n");
|
2016-11-13 14:31:58 -08:00
|
|
|
#endif
|
|
|
|
if (!caml_startup_aux(/* pooling */ caml_cleanup_on_exit))
|
2015-06-19 07:53:38 -07:00
|
|
|
return;
|
2014-05-29 10:39:47 -07:00
|
|
|
|
2017-05-28 14:56:50 -07:00
|
|
|
caml_init_locale();
|
2015-12-30 12:24:10 -08:00
|
|
|
#if defined(_MSC_VER) && __STDC_SECURE_LIB__ >= 200411L
|
2013-01-17 01:04:53 -08:00
|
|
|
caml_install_invalid_parameter_handler();
|
|
|
|
#endif
|
2004-01-01 08:42:43 -08:00
|
|
|
caml_init_custom_operations();
|
|
|
|
caml_ext_table_init(&caml_shared_libs_path, 8);
|
2015-11-20 08:54:26 -08:00
|
|
|
|
2016-11-13 14:31:58 -08:00
|
|
|
/* Determine position of bytecode file */
|
1999-02-14 08:48:25 -08:00
|
|
|
pos = 0;
|
2013-06-18 04:13:01 -07:00
|
|
|
|
|
|
|
/* First, try argv[0] (when ocamlrun is called by a bytecode program) */
|
2002-02-11 05:51:40 -08:00
|
|
|
exe_name = argv[0];
|
2003-12-31 06:20:40 -08:00
|
|
|
fd = caml_attempt_open(&exe_name, &trail, 0);
|
2013-06-18 04:13:01 -07:00
|
|
|
|
2016-09-05 10:13:48 -07:00
|
|
|
/* Little grasshopper wonders why we do that at all, since
|
|
|
|
"The current executable is ocamlrun itself, it's never a bytecode
|
|
|
|
program". Little grasshopper "ocamlc -custom" in mind should keep.
|
|
|
|
With -custom, we have an executable that is ocamlrun itself
|
|
|
|
concatenated with the bytecode. So, if the attempt with argv[0]
|
|
|
|
failed, it is worth trying again with executable_name. */
|
2016-09-04 23:49:25 -07:00
|
|
|
if (fd < 0 && (proc_self_exe = caml_executable_name()) != NULL) {
|
2013-06-18 04:13:01 -07:00
|
|
|
exe_name = proc_self_exe;
|
|
|
|
fd = caml_attempt_open(&exe_name, &trail, 0);
|
|
|
|
}
|
|
|
|
|
1999-02-14 08:48:25 -08:00
|
|
|
if (fd < 0) {
|
|
|
|
pos = parse_command_line(argv);
|
2019-04-19 12:17:19 -07:00
|
|
|
if (argv[pos] == 0) {
|
2019-10-18 15:15:51 -07:00
|
|
|
error("no bytecode file specified");
|
2019-04-19 12:17:19 -07:00
|
|
|
}
|
2002-02-11 05:51:40 -08:00
|
|
|
exe_name = argv[pos];
|
2003-12-31 06:20:40 -08:00
|
|
|
fd = caml_attempt_open(&exe_name, &trail, 1);
|
1999-02-14 08:48:25 -08:00
|
|
|
switch(fd) {
|
|
|
|
case FILE_NOT_FOUND:
|
2019-10-18 15:15:51 -07:00
|
|
|
error("cannot find file '%s'",
|
2017-08-12 13:24:41 -07:00
|
|
|
caml_stat_strdup_of_os(argv[pos]));
|
1999-02-14 08:48:25 -08:00
|
|
|
break;
|
2001-02-19 02:01:41 -08:00
|
|
|
case BAD_BYTECODE:
|
2019-10-18 15:15:51 -07:00
|
|
|
error(
|
2018-05-17 06:17:04 -07:00
|
|
|
"the file '%s' is not a bytecode executable file",
|
2017-09-21 03:29:03 -07:00
|
|
|
caml_stat_strdup_of_os(exe_name));
|
1999-02-14 08:48:25 -08:00
|
|
|
break;
|
2018-05-15 06:15:06 -07:00
|
|
|
case WRONG_MAGIC:
|
2019-10-18 15:15:51 -07:00
|
|
|
error(
|
2018-05-15 06:15:06 -07:00
|
|
|
"the file '%s' has not the right magic number: "\
|
|
|
|
"expected %s, got %s",
|
|
|
|
caml_stat_strdup_of_os(exe_name),
|
|
|
|
EXEC_MAGIC,
|
|
|
|
magicstr);
|
|
|
|
break;
|
1997-06-13 08:49:36 -07:00
|
|
|
}
|
1999-02-14 08:48:25 -08:00
|
|
|
}
|
2000-03-05 11:18:50 -08:00
|
|
|
/* Read the table of contents (section descriptors) */
|
2003-12-31 06:20:40 -08:00
|
|
|
caml_read_section_descriptors(fd, &trail);
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Initialize the abstract machine */
|
2015-05-04 08:44:40 -07:00
|
|
|
caml_init_gc (caml_init_minor_heap_wsz, caml_init_heap_wsz,
|
|
|
|
caml_init_heap_chunk_sz, caml_init_percent_free,
|
2018-11-06 04:42:48 -08:00
|
|
|
caml_init_max_percent_free, caml_init_major_window,
|
|
|
|
caml_init_custom_major_ratio, caml_init_custom_minor_ratio,
|
|
|
|
caml_init_custom_minor_max_bsz);
|
2015-05-04 08:44:40 -07:00
|
|
|
caml_init_stack (caml_init_max_stack_wsz);
|
|
|
|
caml_init_atom_table();
|
2015-08-21 23:04:22 -07:00
|
|
|
caml_init_backtrace();
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Initialize the interpreter */
|
2004-01-01 08:42:43 -08:00
|
|
|
caml_interprete(NULL, 0);
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Initialize the debugger, if needed */
|
2004-01-01 08:42:43 -08:00
|
|
|
caml_debugger_init();
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Load the code */
|
2004-01-02 11:23:29 -08:00
|
|
|
caml_code_size = caml_seek_section(fd, &trail, "CODE");
|
|
|
|
caml_load_code(fd, caml_code_size);
|
2015-02-08 06:10:12 -08:00
|
|
|
caml_init_debug_info();
|
2001-08-28 07:47:48 -07:00
|
|
|
/* Build the table of primitives */
|
2017-09-21 03:29:03 -07:00
|
|
|
shared_lib_path = read_section_to_os(fd, &trail, "DLPT");
|
|
|
|
shared_libs = read_section_to_os(fd, &trail, "DLLS");
|
2001-08-28 07:47:48 -07:00
|
|
|
req_prims = read_section(fd, &trail, "PRIM");
|
2018-05-17 06:17:04 -07:00
|
|
|
if (req_prims == NULL) caml_fatal_error("no PRIM section");
|
2004-01-01 08:42:43 -08:00
|
|
|
caml_build_primitive_table(shared_lib_path, shared_libs, req_prims);
|
2003-12-31 06:20:40 -08:00
|
|
|
caml_stat_free(shared_lib_path);
|
|
|
|
caml_stat_free(shared_libs);
|
|
|
|
caml_stat_free(req_prims);
|
2015-12-08 05:33:20 -08:00
|
|
|
/* Load the globals */
|
|
|
|
caml_seek_section(fd, &trail, "DATA");
|
|
|
|
chan = caml_open_descriptor_in(fd);
|
2020-06-24 07:54:25 -07:00
|
|
|
Lock(chan);
|
2015-12-08 05:33:20 -08:00
|
|
|
caml_global_data = caml_input_val(chan);
|
2020-06-24 07:54:25 -07:00
|
|
|
Unlock(chan);
|
2015-12-08 05:33:20 -08:00
|
|
|
caml_close_channel(chan); /* this also closes fd */
|
2003-12-31 06:20:40 -08:00
|
|
|
caml_stat_free(trail.section);
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Ensure that the globals are in the major heap. */
|
2003-12-31 06:20:40 -08:00
|
|
|
caml_oldify_one (caml_global_data, &caml_global_data);
|
|
|
|
caml_oldify_mopup ();
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Initialize system libraries */
|
2003-12-16 10:09:44 -08:00
|
|
|
caml_sys_init(exe_name, argv + pos);
|
2018-12-11 01:17:04 -08:00
|
|
|
/* Load debugging info, if b>=2 */
|
|
|
|
caml_load_main_debug_info();
|
2000-01-31 21:41:23 -08:00
|
|
|
#ifdef _WIN32
|
2000-03-05 11:18:50 -08:00
|
|
|
/* Start a thread to handle signals */
|
2019-04-14 00:13:24 -07:00
|
|
|
if (caml_secure_getenv(T("CAMLSIGPIPE")))
|
2001-10-01 20:08:45 -07:00
|
|
|
_beginthread(caml_signal_thread, 4096, NULL);
|
2000-01-31 21:41:23 -08:00
|
|
|
#endif
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Execute the program */
|
2019-05-02 08:05:15 -07:00
|
|
|
caml_debugger(PROGRAM_START, Val_unit);
|
2004-01-02 11:23:29 -08:00
|
|
|
res = caml_interprete(caml_start_code, caml_code_size);
|
1999-02-14 08:48:25 -08:00
|
|
|
if (Is_exception_result(res)) {
|
2019-06-07 03:49:28 -07:00
|
|
|
Caml_state->exn_bucket = Extract_exception(res);
|
2004-01-01 08:42:43 -08:00
|
|
|
if (caml_debugger_in_use) {
|
2019-06-07 03:49:28 -07:00
|
|
|
Caml_state->extern_sp = &Caml_state->exn_bucket; /* The debugger needs the
|
2004-01-01 08:42:43 -08:00
|
|
|
exception value.*/
|
2019-05-02 08:05:15 -07:00
|
|
|
caml_debugger(UNCAUGHT_EXC, Val_unit);
|
2001-02-19 04:29:00 -08:00
|
|
|
}
|
2019-06-07 03:49:28 -07:00
|
|
|
caml_fatal_uncaught_exception(Caml_state->exn_bucket);
|
1996-07-24 05:58:12 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1996-11-07 02:57:59 -08:00
|
|
|
/* Main entry point when code is linked in as initialized data */
|
|
|
|
|
2017-02-21 02:49:12 -08:00
|
|
|
CAMLexport value caml_startup_code_exn(
|
2004-02-22 07:07:51 -08:00
|
|
|
code_t code, asize_t code_size,
|
|
|
|
char *data, asize_t data_size,
|
|
|
|
char *section_table, asize_t section_table_size,
|
2016-11-13 13:31:36 -08:00
|
|
|
int pooling,
|
2017-09-21 03:29:03 -07:00
|
|
|
char_os **argv)
|
1996-11-07 02:57:59 -08:00
|
|
|
{
|
2017-09-21 03:29:03 -07:00
|
|
|
char_os * cds_file;
|
|
|
|
char_os * exe_name;
|
1996-11-07 02:57:59 -08:00
|
|
|
|
2019-06-17 22:47:26 -07:00
|
|
|
/* Initialize the domain */
|
|
|
|
caml_init_domain();
|
2016-11-13 14:31:58 -08:00
|
|
|
/* Determine options */
|
|
|
|
#ifdef DEBUG
|
|
|
|
caml_verb_gc = 0x3F;
|
|
|
|
#endif
|
|
|
|
caml_parse_ocamlrunparam();
|
2019-11-15 04:52:35 -08:00
|
|
|
CAML_EVENTLOG_INIT();
|
2016-11-13 14:31:58 -08:00
|
|
|
#ifdef DEBUG
|
2017-02-27 08:32:44 -08:00
|
|
|
caml_gc_message (-1, "### OCaml runtime: debug mode ###\n");
|
2016-11-13 14:31:58 -08:00
|
|
|
#endif
|
|
|
|
if (caml_cleanup_on_exit)
|
|
|
|
pooling = 1;
|
2016-11-13 13:31:36 -08:00
|
|
|
if (!caml_startup_aux(pooling))
|
2015-06-19 07:53:38 -07:00
|
|
|
return Val_unit;
|
|
|
|
|
2017-05-28 14:56:50 -07:00
|
|
|
caml_init_locale();
|
2015-12-30 12:24:10 -08:00
|
|
|
#if defined(_MSC_VER) && __STDC_SECURE_LIB__ >= 200411L
|
2013-01-17 01:04:53 -08:00
|
|
|
caml_install_invalid_parameter_handler();
|
|
|
|
#endif
|
2004-01-01 08:42:43 -08:00
|
|
|
caml_init_custom_operations();
|
2019-04-14 00:13:24 -07:00
|
|
|
cds_file = caml_secure_getenv(T("CAML_DEBUG_FILE"));
|
2010-01-20 08:26:46 -08:00
|
|
|
if (cds_file != NULL) {
|
2017-09-21 03:29:03 -07:00
|
|
|
caml_cds_file = caml_stat_strdup_os(cds_file);
|
2010-01-20 08:26:46 -08:00
|
|
|
}
|
2016-09-04 23:49:25 -07:00
|
|
|
exe_name = caml_executable_name();
|
|
|
|
if (exe_name == NULL) exe_name = caml_search_exe_in_path(argv[0]);
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Initialize the abstract machine */
|
2015-05-04 08:44:40 -07:00
|
|
|
caml_init_gc (caml_init_minor_heap_wsz, caml_init_heap_wsz,
|
|
|
|
caml_init_heap_chunk_sz, caml_init_percent_free,
|
2018-11-06 04:42:48 -08:00
|
|
|
caml_init_max_percent_free, caml_init_major_window,
|
|
|
|
caml_init_custom_major_ratio, caml_init_custom_minor_ratio,
|
|
|
|
caml_init_custom_minor_max_bsz);
|
2015-05-04 08:44:40 -07:00
|
|
|
caml_init_stack (caml_init_max_stack_wsz);
|
|
|
|
caml_init_atom_table();
|
2015-08-21 23:04:22 -07:00
|
|
|
caml_init_backtrace();
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Initialize the interpreter */
|
2004-01-01 08:42:43 -08:00
|
|
|
caml_interprete(NULL, 0);
|
2010-01-20 08:26:46 -08:00
|
|
|
/* Initialize the debugger, if needed */
|
|
|
|
caml_debugger_init();
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Load the code */
|
2004-01-02 11:23:29 -08:00
|
|
|
caml_start_code = code;
|
2010-01-20 08:26:46 -08:00
|
|
|
caml_code_size = code_size;
|
2012-07-16 03:36:00 -07:00
|
|
|
caml_init_code_fragments();
|
2015-05-05 07:16:22 -07:00
|
|
|
caml_init_debug_info();
|
1997-02-02 06:53:44 -08:00
|
|
|
#ifdef THREADED_CODE
|
2004-01-02 11:23:29 -08:00
|
|
|
caml_thread_code(caml_start_code, code_size);
|
1997-02-02 06:53:44 -08:00
|
|
|
#endif
|
2001-08-28 07:47:48 -07:00
|
|
|
/* Use the builtin table of primitives */
|
2004-02-22 07:07:51 -08:00
|
|
|
caml_build_primitive_table_builtin();
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Load the globals */
|
2004-02-22 07:07:51 -08:00
|
|
|
caml_global_data = caml_input_value_from_block(data, data_size);
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Ensure that the globals are in the major heap. */
|
2003-12-31 06:20:40 -08:00
|
|
|
caml_oldify_one (caml_global_data, &caml_global_data);
|
|
|
|
caml_oldify_mopup ();
|
2004-02-22 07:07:51 -08:00
|
|
|
/* Record the sections (for caml_get_section_table in meta.c) */
|
|
|
|
caml_section_table = section_table;
|
|
|
|
caml_section_table_size = section_table_size;
|
2010-01-20 08:26:46 -08:00
|
|
|
/* Initialize system libraries */
|
2012-07-10 05:58:12 -07:00
|
|
|
caml_sys_init(exe_name, argv);
|
2018-12-11 01:17:04 -08:00
|
|
|
/* Load debugging info, if b>=2 */
|
|
|
|
caml_load_main_debug_info();
|
2010-01-20 08:26:46 -08:00
|
|
|
/* Execute the program */
|
2019-05-02 08:05:15 -07:00
|
|
|
caml_debugger(PROGRAM_START, Val_unit);
|
2017-02-21 02:49:12 -08:00
|
|
|
return caml_interprete(caml_start_code, caml_code_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
CAMLexport void caml_startup_code(
|
|
|
|
code_t code, asize_t code_size,
|
|
|
|
char *data, asize_t data_size,
|
|
|
|
char *section_table, asize_t section_table_size,
|
2016-11-13 13:31:36 -08:00
|
|
|
int pooling,
|
2017-09-21 03:29:03 -07:00
|
|
|
char_os **argv)
|
2017-02-21 02:49:12 -08:00
|
|
|
{
|
|
|
|
value res;
|
|
|
|
|
|
|
|
res = caml_startup_code_exn(code, code_size, data, data_size,
|
|
|
|
section_table, section_table_size,
|
2016-11-13 13:31:36 -08:00
|
|
|
pooling, argv);
|
2010-01-20 08:26:46 -08:00
|
|
|
if (Is_exception_result(res)) {
|
2019-06-07 03:49:28 -07:00
|
|
|
Caml_state->exn_bucket = Extract_exception(res);
|
2010-01-20 08:26:46 -08:00
|
|
|
if (caml_debugger_in_use) {
|
2019-06-07 03:49:28 -07:00
|
|
|
Caml_state->extern_sp = &Caml_state->exn_bucket; /* The debugger needs the
|
2010-01-20 08:26:46 -08:00
|
|
|
exception value.*/
|
2019-05-02 08:05:15 -07:00
|
|
|
caml_debugger(UNCAUGHT_EXC, Val_unit);
|
2010-01-20 08:26:46 -08:00
|
|
|
}
|
2019-06-07 03:49:28 -07:00
|
|
|
caml_fatal_uncaught_exception(Caml_state->exn_bucket);
|
2010-01-20 08:26:46 -08:00
|
|
|
}
|
1996-11-07 02:57:59 -08:00
|
|
|
}
|