From 689fa6e2b2c0d29f2ca330f979f8e9d21635a467 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 3 Nov 2020 13:16:33 -0700 Subject: [PATCH] cs: adjust how boot images get to Chez Scheme Change the way boot images are sent to Chez Scheme by the Racket CS wrapper, especially in the case where boot images are embedded in an executable (which is always true for a distriution build). The revised approach avoids a little filesystem work, and it may help Chez Scheme pull bytes in faster. --- .makefile | 2 +- Makefile | 12 +- .../scribblings/inside/cs-start.scrbl | 18 +- racket/src/ChezScheme/c/fasl.c | 1 - racket/src/ChezScheme/c/scheme.c | 224 ++++++++++-------- racket/src/ChezScheme/csug/foreign.stex | 17 ++ racket/src/ChezScheme/s/mkheader.ss | 1 + racket/src/cs/c/boot.c | 39 ++- racket/src/cs/c/boot.h | 6 +- racket/src/cs/c/embed-boot.rkt | 8 +- racket/src/cs/c/main.c | 13 +- 11 files changed, 207 insertions(+), 134 deletions(-) diff --git a/.makefile b/.makefile index c4a944ee3e..4cd22795eb 100644 --- a/.makefile +++ b/.makefile @@ -338,7 +338,7 @@ RACKET_FOR_BOOTFILES = $(RACKET) RACKET_FOR_BUILD = $(RACKET) # This branch name changes each time the pb boot files are updated: -PB_BRANCH == circa-7.9.0.2-3 +PB_BRANCH == circa-7.9.0.3-2 PB_REPO = https://github.com/racket/pb # Alternative source for Chez Scheme boot files, normally set by diff --git a/Makefile b/Makefile index ed6b30b347..48a86f81c8 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ RACKETCS_SUFFIX = RACKET = RACKET_FOR_BOOTFILES = $(RACKET) RACKET_FOR_BUILD = $(RACKET) -PB_BRANCH = circa-7.9.0.2-3 +PB_BRANCH = circa-7.9.0.3-2 PB_REPO = https://github.com/racket/pb EXTRA_REPOS_BASE = CS_CROSS_SUFFIX = @@ -306,14 +306,14 @@ maybe-fetch-pb-as-is: echo done fetch-pb-from: mkdir -p racket/src/ChezScheme/boot - if [ ! -d racket/src/ChezScheme/boot/pb ] ; then git clone -q -b circa-7.9.0.2-3 $(PB_REPO) racket/src/ChezScheme/boot/pb ; else cd racket/src/ChezScheme/boot/pb && git fetch -q origin circa-7.9.0.2-3:remotes/origin/circa-7.9.0.2-3 ; fi - cd racket/src/ChezScheme/boot/pb && git checkout -q circa-7.9.0.2-3 + if [ ! -d racket/src/ChezScheme/boot/pb ] ; then git clone -q -b circa-7.9.0.3-2 $(PB_REPO) racket/src/ChezScheme/boot/pb ; else cd racket/src/ChezScheme/boot/pb && git fetch -q origin circa-7.9.0.3-2:remotes/origin/circa-7.9.0.3-2 ; fi + cd racket/src/ChezScheme/boot/pb && git checkout -q circa-7.9.0.3-2 pb-stage: - cd racket/src/ChezScheme/boot/pb && git branch circa-7.9.0.2-3 - cd racket/src/ChezScheme/boot/pb && git checkout circa-7.9.0.2-3 + cd racket/src/ChezScheme/boot/pb && git branch circa-7.9.0.3-2 + cd racket/src/ChezScheme/boot/pb && git checkout circa-7.9.0.3-2 cd racket/src/ChezScheme/boot/pb && git add . && git commit --amend -m "new build" pb-push: - cd racket/src/ChezScheme/boot/pb && git push -u origin circa-7.9.0.2-3 + cd racket/src/ChezScheme/boot/pb && git push -u origin circa-7.9.0.3-2 win-cs-base: IF "$(RACKET_FOR_BUILD)" == "" $(MAKE) win-bc-then-cs-base SETUP_BOOT_MODE=--boot WIN32_BUILD_LEVEL=bc PLAIN_RACKET=racket\racketbc DISABLE_STATIC_LIBS="$(DISABLE_STATIC_LIBS)" EXTRA_REPOS_BASE="$(EXTRA_REPOS_BASE)" JOB_OPTIONS="$(JOB_OPTIONS)" PLT_SETUP_OPTIONS="$(PLT_SETUP_OPTIONS)" RACKETBC_SUFFIX="$(RACKETBC_SUFFIX)" RACKETCS_SUFFIX="$(RACKETCS_SUFFIX)" IF not "$(RACKET_FOR_BUILD)" == "" $(MAKE) win-just-cs-base SETUP_BOOT_MODE=--chain DISABLE_STATIC_LIBS="$(DISABLE_STATIC_LIBS)" EXTRA_REPOS_BASE="$(EXTRA_REPOS_BASE)" JOB_OPTIONS="$(JOB_OPTIONS)" PLT_SETUP_OPTIONS="$(PLT_SETUP_OPTIONS)" RACKETCS_SUFFIX="$(RACKETCS_SUFFIX)" RACKET_FOR_BUILD="$(RACKET_FOR_BUILD)" diff --git a/pkgs/racket-doc/scribblings/inside/cs-start.scrbl b/pkgs/racket-doc/scribblings/inside/cs-start.scrbl index 0274111995..6ade3777f1 100644 --- a/pkgs/racket-doc/scribblings/inside/cs-start.scrbl +++ b/pkgs/racket-doc/scribblings/inside/cs-start.scrbl @@ -40,19 +40,31 @@ Fields in @cppdef{racket_boot_arguments_t}: The image as distributed is self-terminating, so no size or ending offset is needed.} + @item{@cpp{long} @cppdef{boot1_len} --- an optional length in bytes + for the first boot image, which is used as a hint for loading + the boot file if non-zero. If this hint is provided, it must be + at least as large as the boot image bytes, and it must be no + longer than the file size after the boot image offset.} + @item{@cpp{const char *} @cppdef{boot2_path} --- like @cpp{boot1_path}, but for the image that contains compiler functionality, normally called @filepath{scheme.boot}.} @item{@cpp{long} @cppdef{boot2_offset} --- an offset into @cpp{boot2_path} to read for the second boot image.} - + + @item{@cpp{long} @cppdef{boot2_len} --- @cpp{boot1_len}, an optional + length in bytes for the second boot image.} + @item{@cpp{const char *} @cppdef{boot3_path} --- like @cpp{boot1_path}, but for the image that contains Racket functionality, normally called @filepath{racket.boot}.} - @item{@cpp{long} @cppdef{boot3_offset} --- an offset into - @cpp{boot2_path} to read for the thirf boot image.} + @item{@cpp{long} @cppdef{boot3_offset} --- @cpp{boot1_len}, an offset + into @cpp{boot2_path} to read for the third boot image.} + + @item{@cpp{long} @cppdef{boot3_len} --- an optional length in bytes + for the third boot image.} @item{@cpp{int} @cpp{argc} and @cpp{char **} @cpp{argv} --- command-line arguments to be processed the same as for a diff --git a/racket/src/ChezScheme/c/fasl.c b/racket/src/ChezScheme/c/fasl.c index 6f157bc699..319a2cef55 100644 --- a/racket/src/ChezScheme/c/fasl.c +++ b/racket/src/ChezScheme/c/fasl.c @@ -320,7 +320,6 @@ ptr S_bv_fasl_read(ptr bv, int ty, uptr offset, uptr len, ptr path, ptr external ptr tc = get_thread_context(); ptr x; struct unbufFaslFileObj uffo; - /* acquire mutex in case we modify code pages */ uffo.path = path; uffo.type = UFFO_TYPE_BV; x = bv_fasl_entry(tc, bv, ty, offset, len, &uffo, externals); diff --git a/racket/src/ChezScheme/c/scheme.c b/racket/src/ChezScheme/c/scheme.c index 412db41c15..c7514eb06b 100644 --- a/racket/src/ChezScheme/c/scheme.c +++ b/racket/src/ChezScheme/c/scheme.c @@ -577,6 +577,9 @@ static IBOOL next_path(path, name, ext, sp, dsp) char *path; const char *name, * typedef struct { INT fd; + iptr len; /* 0 => unknown */ + iptr offset; + IBOOL need_check, close_after; char path[PATH_MAX]; } boot_desc; @@ -587,11 +590,83 @@ static boot_desc bd[MAX_BOOT_FILES]; static octet get_u8 PROTO((INT fd)); static uptr get_uptr PROTO((INT fd, uptr *pn)); static INT get_string PROTO((INT fd, char *s, iptr max, INT *c)); -static IBOOL find_boot PROTO((const char *name, const char *ext, IBOOL direct_pathp, int fd, IBOOL errorp)); static void load PROTO((ptr tc, iptr n, IBOOL base)); static void check_boot_file_state PROTO((const char *who)); -static IBOOL find_boot(name, ext, direct_pathp, fd, errorp) const char *name, *ext; int fd; IBOOL direct_pathp, errorp; { +static IBOOL check_boot(int fd, IBOOL verbose, const char *path) { + uptr n = 0; + + /* check for magic number */ + if (get_u8(fd) != fasl_type_header || + get_u8(fd) != 0 || + get_u8(fd) != 0 || + get_u8(fd) != 0 || + get_u8(fd) != 'c' || + get_u8(fd) != 'h' || + get_u8(fd) != 'e' || + get_u8(fd) != 'z') { + if (verbose) fprintf(stderr, "malformed fasl-object header in %s\n", path); + CLOSE(fd); + return 0; + } + + /* check version */ + if (get_uptr(fd, &n) != 0) { + if (verbose) fprintf(stderr, "unexpected end of file on %s\n", path); + CLOSE(fd); + return 0; + } + + if (n != scheme_version) { + if (verbose) { + fprintf(stderr, "%s is for Version %s; ", path, S_format_scheme_version(n)); + /* use separate fprintf since S_format_scheme_version returns static string */ + fprintf(stderr, "need Version %s\n", S_format_scheme_version(scheme_version)); + } + CLOSE(fd); + return 0; + } + + /* check machine type */ + if (get_uptr(fd, &n) != 0) { + if (verbose) fprintf(stderr, "unexpected end of file on %s\n", path); + CLOSE(fd); + return 0; + } + + if (n != machine_type) { + if (verbose) + fprintf(stderr, "%s is for machine-type %s; need machine-type %s\n", path, + S_lookup_machine_type(n), S_lookup_machine_type(machine_type)); + CLOSE(fd); + return 0; + } + + return 1; +} + +static void check_dependencies_header(int fd, const char *path) { + if (get_u8(fd) != '(') { /* ) */ + fprintf(stderr, "malformed boot file %s\n", path); + CLOSE(fd); + S_abnormal_exit(); + } +} + +static void finish_dependencies_header(int fd, const char *path, int c) { + while (c != ')') { + if (c < 0) { + fprintf(stderr, "malformed boot file %s\n", path); + CLOSE(fd); + S_abnormal_exit(); + } + c = get_u8(fd); + } +} + +static IBOOL find_boot(const char *name, const char *ext, IBOOL direct_pathp, + int fd, + IBOOL errorp) { char pathbuf[PATH_MAX], buf[PATH_MAX]; uptr n = 0; INT c; @@ -623,53 +698,14 @@ static IBOOL find_boot(name, ext, direct_pathp, fd, errorp) const char *name, *e } if (verbose) fprintf(stderr, "trying %s...opened\n", path); - /* check for magic number */ - if (get_u8(fd) != fasl_type_header || - get_u8(fd) != 0 || - get_u8(fd) != 0 || - get_u8(fd) != 0 || - get_u8(fd) != 'c' || - get_u8(fd) != 'h' || - get_u8(fd) != 'e' || - get_u8(fd) != 'z') { - fprintf(stderr, "malformed fasl-object header in %s\n", path); + if (!check_boot(fd, 1, path)) S_abnormal_exit(); - } - - /* check version */ - if (get_uptr(fd, &n) != 0) { - fprintf(stderr, "unexpected end of file on %s\n", path); - CLOSE(fd); - S_abnormal_exit(); - } - - if (n != scheme_version) { - fprintf(stderr, "%s is for Version %s; ", path, S_format_scheme_version(n)); - /* use separate fprintf since S_format_scheme_version returns static string */ - fprintf(stderr, "need Version %s\n", S_format_scheme_version(scheme_version)); - CLOSE(fd); - S_abnormal_exit(); - } - - /* check machine type */ - if (get_uptr(fd, &n) != 0) { - fprintf(stderr, "unexpected end of file on %s\n", path); - CLOSE(fd); - S_abnormal_exit(); - } - - if (n != machine_type) { - fprintf(stderr, "%s is for machine-type %s; need machine-type %s\n", path, - S_lookup_machine_type(n), S_lookup_machine_type(machine_type)); - CLOSE(fd); - S_abnormal_exit(); - } } else { const char *sp = Sschemeheapdirs; const char *dsp = Sdefaultheapdirs; path = pathbuf; - for (;;) { + while (1) { if (!next_path(pathbuf, name, ext, &sp, &dsp)) { if (errorp) { fprintf(stderr, "cannot find compatible boot file %s%s in search path:\n \"%s%s\"\n", @@ -692,63 +728,14 @@ static IBOOL find_boot(name, ext, direct_pathp, fd, errorp) const char *name, *e if (verbose) fprintf(stderr, "trying %s...opened\n", path); - /* check for magic number */ - if (get_u8(fd) != fasl_type_header || - get_u8(fd) != 0 || - get_u8(fd) != 0 || - get_u8(fd) != 0 || - get_u8(fd) != 'c' || - get_u8(fd) != 'h' || - get_u8(fd) != 'e' || - get_u8(fd) != 'z') { - if (verbose) fprintf(stderr, "malformed fasl-object header in %s\n", path); - CLOSE(fd); - continue; - } - - /* check version */ - if (get_uptr(fd, &n) != 0) { - if (verbose) fprintf(stderr, "unexpected end of file on %s\n", path); - CLOSE(fd); - continue; - } - - if (n != scheme_version) { - if (verbose) { - fprintf(stderr, "%s is for Version %s; ", path, S_format_scheme_version(n)); - /* use separate fprintf since S_format_scheme_version returns static string */ - fprintf(stderr, "need Version %s\n", S_format_scheme_version(scheme_version)); - } - CLOSE(fd); - continue; - } - - /* check machine type */ - if (get_uptr(fd, &n) != 0) { - if (verbose) fprintf(stderr, "unexpected end of file on %s\n", path); - CLOSE(fd); - continue; - } - - if (n != machine_type) { - if (verbose) - fprintf(stderr, "%s is for machine-type %s; need machine-type %s\n", path, - S_lookup_machine_type(n), S_lookup_machine_type(machine_type)); - CLOSE(fd); - continue; - } - - break; + if (check_boot(fd, verbose, path)) + break; } } if (verbose) fprintf(stderr, "version and machine type check\n"); - if (get_u8(fd) != '(') { /* ) */ - fprintf(stderr, "malformed boot file %s\n", path); - CLOSE(fd); - S_abnormal_exit(); - } + check_dependencies_header(fd, path); /* ( */ if ((c = get_u8(fd)) == ')') { @@ -792,14 +779,7 @@ static IBOOL find_boot(name, ext, direct_pathp, fd, errorp) const char *name, *e } /* skip to end of header */ - while (c != ')') { - if (c < 0) { - fprintf(stderr, "malformed boot file %s\n", path); - CLOSE(fd); - S_abnormal_exit(); - } - c = get_u8(fd); - } + finish_dependencies_header(fd, path, c); } if (boot_count >= MAX_BOOT_FILES) { @@ -808,6 +788,10 @@ static IBOOL find_boot(name, ext, direct_pathp, fd, errorp) const char *name, *e } bd[boot_count].fd = fd; + bd[boot_count].offset = 0; + bd[boot_count].len = 0; + bd[boot_count].need_check = 0; + bd[boot_count].close_after = 1; strcpy(bd[boot_count].path, path); boot_count += 1; @@ -883,6 +867,16 @@ static void boot_element(ptr tc, ptr x, iptr n) { static void load(tc, n, base) ptr tc; iptr n; IBOOL base; { ptr x; iptr i; + if (bd[n].need_check) { + if (LSEEK(bd[n].fd, bd[n].offset, SEEK_SET) != bd[n].offset) { + fprintf(stderr, "seek in boot file %s failed\n", bd[n].path); + S_abnormal_exit(); + } + check_boot(bd[n].fd, 1, bd[n].path); + check_dependencies_header(bd[n].fd, bd[n].path); + finish_dependencies_header(bd[n].fd, bd[n].path, 0); + } + if (base) { S_G.error_invoke_code_object = S_boot_read(bd[n].fd, bd[n].path); if (!Scodep(S_G.error_invoke_code_object)) { @@ -919,7 +913,8 @@ static void load(tc, n, base) ptr tc; iptr n; IBOOL base; { } S_G.load_binary = Sfalse; - CLOSE(bd[n].fd); + if (bd[n].close_after) + CLOSE(bd[n].fd); } /***************************************************************************/ @@ -1060,6 +1055,27 @@ extern void Sregister_boot_file_fd(name, fd) const char *name; int fd; { find_boot(name, "", 1, fd, 1); } +extern void Sregister_boot_file_fd_region(const char *name, + int fd, + iptr offset, + iptr len, + int close_after) { + check_boot_file_state("Sregister_boot_file_fd"); + + if (strlen(name) >= PATH_MAX) { + fprintf(stderr, "boot-file path is too long %s\n", name); + S_abnormal_exit(); + } + + bd[boot_count].fd = fd; + bd[boot_count].offset = offset; + bd[boot_count].len = len; + bd[boot_count].need_check = 1; + bd[boot_count].close_after = close_after; + strcpy(bd[boot_count].path, name); + boot_count += 1; +} + extern void Sregister_heap_file(UNUSED const char *path) { fprintf(stderr, "Sregister_heap_file: saved heap files are not presently supported\n"); S_abnormal_exit(); diff --git a/racket/src/ChezScheme/csug/foreign.stex b/racket/src/ChezScheme/csug/foreign.stex index b0a558aefd..53d96c3ba4 100644 --- a/racket/src/ChezScheme/csug/foreign.stex +++ b/racket/src/ChezScheme/csug/foreign.stex @@ -2807,6 +2807,9 @@ cause problems. \xdef\cfunction#1#2#3{\noindent\index{\scheme{#2}}% [func] \scheme{#1} \scheme{#2}\scheme{(#3)}\\} +\xdef\cfunctTwo#1#2#3#4{\noindent\index{\scheme{#2}}% +[func] \scheme{#1} \scheme{#2}\scheme{(#3}\\\hphantom{[func] \scheme{#1} \scheme{#2}\scheme{(}}\scheme{#4)}\\} + \parheader{Customization} The functions described here are used to initialize the Scheme system, build the Scheme heap, and run the Scheme system from a separate @@ -2817,6 +2820,7 @@ program. \cfunction{void}{Sset_verbose}{int \var{v}} \cfunction{void}{Sregister_boot_file}{const char *\var{name}} \cfunction{void}{Sregister_boot_file_fd}{const char *\var{name}, int \var{fd}} +\cfunctTwo{void}{Sregister_boot_file_fd_segment}{const char *\var{name}, int \var{fd},}{iptr \var{offset}, iptr \var{len}, int \var{close}_\var{after}} \cfunction{void}{Sbuild_heap}{const char *\var{exec}, void (*\var{custom}_\var{init})(void)} \cfunction{void}{Senable_expeditor}{const char *\var{history}_\var{file}} \cfunction{void}{Sretain_static_relocation}{void} @@ -2858,6 +2862,19 @@ For the first boot file registered only, the system also searches for the boot files upon which the named file depends, either directly or indirectly. +The \scheme{Sregister_boot_file_fd_region} function is an alternative +to \scheme{Sregister_boot_file_fd} that allows the same file +descriptor to be used for multiple boot files using different offsets +into the file. The \var{len} argument is used as a hint, but it can be +0 to mean that the size is unknown, or it can be larger than the +actual boot content; it must not be non-0 and smaller than the boot +content, and the boot content must be self-terminating independent +of]var{len}. No search is performed for dependencies. If the same file +descriptor is used for multiple boot files, then +\scheme{\var{close}_\var{after}} should be non-zero only for the last +one. The boot file content is read only when \scheme{Sbuild_heap} is +called. + \scheme{Sbuild_heap} creates the Scheme heap from the registered boot files. \var{exec} is assumed to be the name of or path to the executable diff --git a/racket/src/ChezScheme/s/mkheader.ss b/racket/src/ChezScheme/s/mkheader.ss index 3e1cb5ee3d..19689c8fe5 100644 --- a/racket/src/ChezScheme/s/mkheader.ss +++ b/racket/src/ChezScheme/s/mkheader.ss @@ -424,6 +424,7 @@ (export "void" "Sregister_boot_file" "(const char *)") (export "void" "Sregister_boot_direct_file" "(const char *)") (export "void" "Sregister_boot_file_fd" "(const char *, int fd)") + (export "void" "Sregister_boot_file_fd_region" "(const char *, int fd, iptr offset, iptr len, int close_after)") (export "void" "Sregister_heap_file" "(const char *)") (export "void" "Scompact_heap" "(void)") (export "void" "Ssave_heap" "(const char *, int)") diff --git a/racket/src/cs/c/boot.c b/racket/src/cs/c/boot.c index b21afbeb91..8f2dd6f662 100644 --- a/racket/src/cs/c/boot.c +++ b/racket/src/cs/c/boot.c @@ -114,24 +114,41 @@ void racket_boot(racket_boot_arguments_t *ba) if ((ba->argc == 4) && !strcmp(ba->argv[0], "--cross-server")) cross_server = 1; + /* Open boot files, but reuse file descriptors when possible */ { - int fd1, fd2; + int fd1, fd2, close_fd1 = 0, close_fd2 = 0; + + if ((ba->boot2_offset == 0) + || ((ba->boot1_path != ba->boot2_path) + && strcmp(ba->boot1_path, ba->boot2_path))) + close_fd1 = 1; +# ifdef RACKET_AS_BOOT + if ((ba->boot3_offset == 0) + || ((ba->boot2_path != ba->boot3_path) + && strcmp(ba->boot2_path, ba->boot3_path))) + close_fd2 = 1; +#else + close_fd2 = 1; +#endif fd1 = open(ba->boot1_path, O_RDONLY | BOOT_O_BINARY); - lseek(fd1, ba->boot1_offset, SEEK_SET); - Sregister_boot_file_fd("petite", fd1); - - fd2 = open(ba->boot2_path, O_RDONLY | BOOT_O_BINARY); - lseek(fd2, ba->boot2_offset, SEEK_SET); - Sregister_boot_file_fd("scheme", fd2); + Sregister_boot_file_fd_region("petite", fd1, ba->boot1_offset, ba->boot1_len, close_fd1); + + if (!close_fd1) + fd2 = fd1; + else + fd2 = open(ba->boot2_path, O_RDONLY | BOOT_O_BINARY); + Sregister_boot_file_fd_region("scheme", fd2, ba->boot2_offset, ba->boot2_len, close_fd2); # ifdef RACKET_AS_BOOT if (!cross_server) { int fd3; - - fd3 = open(ba->boot3_path, O_RDONLY | BOOT_O_BINARY); - lseek(fd3, ba->boot3_offset, SEEK_SET); - Sregister_boot_file_fd("racket", fd3); + + if (!close_fd2) + fd3 = fd2; + else + fd3 = open(ba->boot3_path, O_RDONLY | BOOT_O_BINARY); + Sregister_boot_file_fd_region("racket", fd3, ba->boot3_offset, ba->boot3_len, 1); } # endif } diff --git a/racket/src/cs/c/boot.h b/racket/src/cs/c/boot.h index c441f5c214..f9560ba94c 100644 --- a/racket/src/cs/c/boot.h +++ b/racket/src/cs/c/boot.h @@ -6,14 +6,16 @@ typedef struct racket_boot_arguments_t { /* Boot files --- potentially the same path with different offsets. If a boot image is embedded in a larger file, it must be - terminated with "\0 if the boot image is compressed or "\177" if - the boot image is uncompressed. */ + terminated with "\177". */ const char *boot1_path; /* REQUIRED; path to "petite.boot" */ long boot1_offset; + long boot1_len; /* 0 => unknown length */ const char *boot2_path; /* REQUIRED; path to "scheme.boot" */ long boot2_offset; + long boot2_len; /* 0 => unknown length */ const char *boot3_path; /* REQUIRED; path to "racket.boot" */ long boot3_offset; + long boot3_len; /* 0 => unknown length */ /* Command-line arguments are handled in the same way as the `racket` exectuable. The `argv` array should *not* include the diff --git a/racket/src/cs/c/embed-boot.rkt b/racket/src/cs/c/embed-boot.rkt index 62b8612091..ed33e1d9c1 100644 --- a/racket/src/cs/c/embed-boot.rkt +++ b/racket/src/cs/c/embed-boot.rkt @@ -120,8 +120,12 @@ (file-position o (cdar m)) (void (write-bytes (integer->integer-bytes pos 4 #t big-endian?) o)) - (void (write-bytes (integer->integer-bytes (+ pos (bytes-length bstr1) terminator-len) 4 #t big-endian?) o)) - (void (write-bytes (integer->integer-bytes (+ pos (bytes-length bstr1) (bytes-length bstr2) (* 2 terminator-len)) 4 #t big-endian?) o))) + (let ([pos (+ pos (bytes-length bstr1) terminator-len)]) + (void (write-bytes (integer->integer-bytes pos 4 #t big-endian?) o)) + (let ([pos (+ pos (bytes-length bstr2) terminator-len)]) + (void (write-bytes (integer->integer-bytes pos 4 #t big-endian?) o)) + (let ([pos (+ pos (bytes-length bstr3) terminator-len)]) + (void (write-bytes (integer->integer-bytes pos 4 #t big-endian?) o)))))) (cond [(null? alt-dests) diff --git a/racket/src/cs/c/main.c b/racket/src/cs/c/main.c index 8e81eb1afb..fcca0dcf0d 100644 --- a/racket/src/cs/c/main.c +++ b/racket/src/cs/c/main.c @@ -54,7 +54,7 @@ static void scheme_set_dll_procs(scheme_dll_open_proc open, #endif PRESERVE_IN_EXECUTABLE -char *boot_file_data = "BooT FilE OffsetS:\0\0\0\0\0\0\0\0\0\0\0\0"; +char *boot_file_data = "BooT FilE OffsetS:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; static int boot_file_offset = 18; #define USE_GENERIC_GET_SELF_PATH @@ -433,7 +433,7 @@ static int bytes_main(int argc, char **argv, char *boot_exe; char *exec_file = argv[0], *run_file = NULL; char *boot1_path, *boot2_path, *boot3_path; - int boot1_offset, boot2_offset, boot3_offset; + int boot1_offset, boot2_offset, boot3_offset, boot_end_offset; #ifdef OS_X int boot_images_in_exe = 1; #endif @@ -459,6 +459,7 @@ static int bytes_main(int argc, char **argv, memcpy(&boot1_offset, boot_file_data + boot_file_offset, sizeof(boot1_offset)); memcpy(&boot2_offset, boot_file_data + boot_file_offset + 4, sizeof(boot2_offset)); memcpy(&boot3_offset, boot_file_data + boot_file_offset + 8, sizeof(boot3_offset)); + memcpy(&boot_end_offset, boot_file_data + boot_file_offset + 12, sizeof(boot_end_offset)); #ifdef WIN32 parse_embedded_dlls(); @@ -494,6 +495,7 @@ static int bytes_main(int argc, char **argv, boot1_offset += boot_offset; boot2_offset += boot_offset; boot3_offset += boot_offset; + boot_end_offset += boot_offset; boot1_path = boot2_path = boot3_path = boot_exe; @@ -504,7 +506,7 @@ static int bytes_main(int argc, char **argv, boot1_path = path_append(fw_path, "petite.boot"); boot2_path = path_append(fw_path, "scheme.boot"); boot3_path = path_append(fw_path, "racket.boot"); - boot1_offset = boot2_offset = boot3_offset = 0; + boot1_offset = boot2_offset = boot3_offset = boot_end_offset = 0; } } #endif @@ -529,11 +531,14 @@ static int bytes_main(int argc, char **argv, ba.boot1_path = boot1_path; ba.boot1_offset = boot1_offset; + ba.boot1_len = boot2_offset - boot1_offset; ba.boot2_path = boot2_path; ba.boot2_offset = boot2_offset; + ba.boot2_len = boot3_offset - boot2_offset; ba.boot3_path = boot3_path; ba.boot3_offset = boot3_offset; - + ba.boot3_len = boot_end_offset - boot3_offset; + ba.argc = argc; ba.argv = argv; ba.exec_file = exec_file;