clean up self-path and ELF handling for embedding executables
Clean up tangled and partly repeated code, and normalize ELF use for boot files and embedded modules. Also, repair Unix-style Mac OS builds. With these changes, `raco exe` should always produce a well-formed ELF, Mach-O, or PE excutable. The mode that just appends to the end of the executable should happen only platforms that don't use one of those three --- which are very rare and unlikely supported, anyway. Closes #3831
This commit is contained in:
parent
e032be434e
commit
0f743800e4
|
@ -195,7 +195,9 @@ flags:
|
|||
@nonterm{m} and from @nonterm{m} to @nonterm{p}. (On Mac OS,
|
||||
@nonterm{n}, @nonterm{m}, and @nonterm{p} are relative to a
|
||||
@tt{__PLTSCHEME} segment in the executable. On Windows,
|
||||
they are relative to a resource of type 257 and ID 1.) The first range
|
||||
they are relative to a resource of type 257 and ID 1. On Unix
|
||||
using ELF, they are relative to the @tt{.rackprog} segment
|
||||
in the executable.) The first range
|
||||
is loaded in every new @tech{place}, and any modules declared
|
||||
in that range are considered predefined in the sense of
|
||||
@racket[module-predefined?]. This option is normally embedded
|
||||
|
@ -203,7 +205,7 @@ flags:
|
|||
|
||||
@item{@FlagFirst{Y} @nonterm{file} @nonterm{n} @nonterm{m} @nonterm{p} :
|
||||
Like @Flag{k} @nonterm{n} @nonterm{m} @nonterm{p}, but reading
|
||||
from @nonterm{file} (without any adjustment on Mac OS or Windows
|
||||
from @nonterm{file} (without any adjustment
|
||||
for a segment or resource offset).}
|
||||
|
||||
@item{@FlagFirst{m} or @DFlagFirst{main} : Evaluates a call to
|
||||
|
|
|
@ -1511,9 +1511,7 @@
|
|||
(let ([m (assq 'original-exe? aux)])
|
||||
(or (not m)
|
||||
(not (cdr m))))))
|
||||
(define long-cmdline? (or (eq? (cross-system-type) 'windows)
|
||||
(eq? (cross-system-type) 'macosx)
|
||||
unix-starter?))
|
||||
(define long-cmdline? #t)
|
||||
(define relative? (let ([m (assq 'relative? aux)])
|
||||
(and m (cdr m))))
|
||||
(define collects-path-bytes (collects-path->bytes
|
||||
|
@ -1762,15 +1760,18 @@
|
|||
new-rsrcs))
|
||||
(update-resources dest-exe pe new+dll-rsrcs)
|
||||
(values 0 decl-len init-len (+ init-len cmdline-len))]
|
||||
[(and (eq? (cross-system-type) 'macosx)
|
||||
(not unix-starter?))
|
||||
[(memq (cross-system-type 'os*) '(macosx darwin))
|
||||
;; For Mach-O, we know how to add a proper segment
|
||||
(remove-signature dest-exe) ; may be needed in 'darwin mode
|
||||
(define s (open-output-bytes))
|
||||
(define decl-len (write-module s))
|
||||
(let* ([s (get-output-bytes s)]
|
||||
[cl (let ([o (open-output-bytes)])
|
||||
;; position is relative to __PLTSCHEME:
|
||||
(write-cmdline (make-full-cmdline 0 decl-len (bytes-length s)) o)
|
||||
(let ([cmdline (make-full-cmdline 0 decl-len (bytes-length s))])
|
||||
(cond
|
||||
[unix-starter? (display (make-starter-cmdline cmdline) o)]
|
||||
[else (write-cmdline cmdline o)]))
|
||||
(get-output-bytes o))])
|
||||
(let ([start (add-plt-segment
|
||||
dest-exe
|
||||
|
@ -1783,28 +1784,25 @@
|
|||
(+ start (bytes-length s))
|
||||
(+ start (bytes-length s) (bytes-length cl))))))]
|
||||
[else
|
||||
;; Unix starter: Maybe ELF, in which case we
|
||||
;; Unix starter or direct embedding: Maybe ELF, in which case we
|
||||
;; can add a proper section
|
||||
(define-values (s e dl p)
|
||||
(if unix-starter?
|
||||
(add-racket-section
|
||||
orig-exe
|
||||
dest-exe
|
||||
(if launcher? #".rackcmdl" #".rackprog")
|
||||
(lambda (start)
|
||||
(let ([s (open-output-bytes)])
|
||||
(define decl-len (write-module s))
|
||||
(let ([p (file-position s)])
|
||||
(display (make-starter-cmdline
|
||||
(make-full-cmdline start
|
||||
(+ start decl-len)
|
||||
(+ start p)))
|
||||
s)
|
||||
(values (get-output-bytes s) decl-len p)))))
|
||||
(values #f #f #f #f)))
|
||||
(add-racket-section
|
||||
orig-exe
|
||||
dest-exe
|
||||
#".rackprog"
|
||||
(lambda (start)
|
||||
(let ([s (open-output-bytes)])
|
||||
(define decl-len (write-module s))
|
||||
(let ([p (file-position s)])
|
||||
(let ([cmdline (make-full-cmdline 0 decl-len p)])
|
||||
(cond
|
||||
[unix-starter? (display (make-starter-cmdline cmdline) s)]
|
||||
[else (write-cmdline cmdline s)]))
|
||||
(values (get-output-bytes s) decl-len p))))))
|
||||
(if (and s e)
|
||||
;; ELF succeeded:
|
||||
(values s (+ s dl) (+ s p) e)
|
||||
;; ELF succeeded, so make values relative to start:
|
||||
(values 0 dl p (- e s))
|
||||
;; Otherwise, just add to the end of the file:
|
||||
(let ([start (file-size dest-exe)])
|
||||
(define decl-end
|
||||
|
@ -1849,11 +1847,11 @@
|
|||
"exeuctable type"
|
||||
#"bINARy tYPe:"))))]
|
||||
[cmdline (if cmdline-end
|
||||
#f
|
||||
(make-starter-cmdline full-cmdline))]
|
||||
#f
|
||||
(make-starter-cmdline full-cmdline))]
|
||||
[out (open-output-file dest-exe #:exists 'update)])
|
||||
(let ([old-cmdline-end cmdline-end]
|
||||
[cmdline-end (or cmdline-end (+ end (bytes-length cmdline)))]
|
||||
[cmdline-end (or cmdline-end (+ end (bytes-length cmdline)))]
|
||||
[write-num (lambda (n)
|
||||
(write-bytes (integer->integer-bytes n 4 #t #f) out))])
|
||||
(dynamic-wind
|
||||
|
@ -1879,10 +1877,10 @@
|
|||
(write-num (length full-cmdline))
|
||||
(write-num (if mred? 1 0))
|
||||
(flush-output out)
|
||||
(unless old-cmdline-end
|
||||
(file-position out end)
|
||||
(write-bytes cmdline out)
|
||||
(flush-output out)))
|
||||
(unless old-cmdline-end
|
||||
(file-position out end)
|
||||
(write-bytes cmdline out)
|
||||
(flush-output out)))
|
||||
(lambda ()
|
||||
(close-output-port out)))))]
|
||||
[else
|
||||
|
@ -1936,7 +1934,7 @@
|
|||
(assq 'subsystem aux))])
|
||||
(when m
|
||||
(set-subsystem dest-exe (cdr m)))))]))))
|
||||
(when (eq? (cross-system-type) 'macosx)
|
||||
(when (memq (cross-system-type 'os*) '(macosx darwin))
|
||||
(add-ad-hoc-signature dest-exe))
|
||||
(done-writable dest-exe old-perms))))))
|
||||
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
call-with-autorelease))
|
||||
|
||||
;; Make sure Foundation is loaded:
|
||||
(when (eq? 'macosx (system-type))
|
||||
(void (ffi-lib "/System/Library/Frameworks/Foundation.framework/Foundation"
|
||||
#:fail (lambda () #f))))
|
||||
(case (system-type 'os*)
|
||||
[(macosx darwin)
|
||||
(void (ffi-lib "/System/Library/Frameworks/Foundation.framework/Foundation"
|
||||
#:fail (lambda () #f)))])
|
||||
|
||||
(import-class NSAutoreleasePool)
|
||||
|
||||
|
|
|
@ -17,16 +17,19 @@
|
|||
osx-old-openssl?)
|
||||
|
||||
(define (osx-old-openssl?)
|
||||
(and (eq? 'macosx (system-type))
|
||||
(and (or (eq? 'macosx (system-type))
|
||||
(eq? 'darwin (system-type 'os*)))
|
||||
(not (eq? 'ppc (system-type 'arch))) ; Mac OS 10.5 is too old for this to work?
|
||||
(or (not ssl-available?)
|
||||
(not (memq 'tls12 (supported-client-protocols))))))
|
||||
|
||||
(define cf-lib
|
||||
(and (eq? 'macosx (system-type))
|
||||
(and (or (eq? 'macosx (system-type))
|
||||
(eq? 'darwin (system-type 'os*)))
|
||||
(ffi-lib "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")))
|
||||
(define net-lib
|
||||
(and (eq? 'macosx (system-type))
|
||||
(and (or (eq? 'macosx (system-type))
|
||||
(eq? 'darwin (system-type 'os*)))
|
||||
(ffi-lib
|
||||
"/System/Library/Frameworks/CFNetwork.framework/CFNetwork"
|
||||
#:fail (lambda ()
|
||||
|
|
|
@ -479,12 +479,12 @@ TO DO:
|
|||
|
||||
(define ssl-default-verify-sources
|
||||
(make-parameter
|
||||
(case (system-type)
|
||||
(case (system-type 'os*)
|
||||
[(windows)
|
||||
;; On Windows, x509-root-sources produces paths like "/usr/local/ssl/certs", which
|
||||
;; aren't useful. So just skip them.
|
||||
'((win32-store "ROOT"))]
|
||||
[(macosx)
|
||||
[(macosx darwin)
|
||||
'((macosx-keychain "/System/Library/Keychains/SystemRootCertificates.keychain"))]
|
||||
[else
|
||||
(x509-root-sources)])))
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
;; security export -k /System/Library/Keychains/... -t certs -f pemseq -o foo.pem
|
||||
|
||||
(define libcf
|
||||
(case (system-type)
|
||||
[(macosx) (ffi-lib "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
|
||||
(case (system-type 'os*)
|
||||
[(macosx darwin) (ffi-lib "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
|
||||
[else #f]))
|
||||
|
||||
(define-ffi-definer define-cf libcf
|
||||
|
@ -47,8 +47,8 @@
|
|||
;; ----
|
||||
|
||||
(define libsec
|
||||
(case (system-type)
|
||||
[(macosx) (ffi-lib "/System/Library/Frameworks/Security.framework/Security")]
|
||||
(case (system-type 'os*)
|
||||
[(macosx darwin) (ffi-lib "/System/Library/Frameworks/Security.framework/Security")]
|
||||
[else #f]))
|
||||
(define-ffi-definer define-sec libsec
|
||||
#:default-make-fail make-not-available)
|
||||
|
|
|
@ -304,7 +304,7 @@ DEF_C_DIRS = $(DEF_COLLECTS_DIR) $(DEF_CONFIG_DIR)
|
|||
MAIN_HEADER_DEPS = $(srcdir)/include/scheme.h $(srcdir)/include/schthread.h $(srcdir)/sconfig.h \
|
||||
$(srcdir)/src/stypes.h $(srcdir)/cmdline.inc $(srcdir)/../start/parse_cmdl.inc \
|
||||
$(srcdir)/../start/cmdl_to_argv.inc \
|
||||
$(srcdir)/../start/config.inc $(srcdir)/../start/delayed.inc \
|
||||
$(srcdir)/../start/config.inc $(srcdir)/../start/self_exe.inc $(srcdir)/../start/delayed.inc \
|
||||
$(srcdir)/../start/embedded_dll.inc
|
||||
|
||||
MAIN_INCLUDES = -I$(builddir) -I$(srcdir)/include -I$(srcdir)/../version
|
||||
|
@ -499,6 +499,7 @@ unix-install-cgc:
|
|||
cd ..; $(STRIP_DEBUG) "$(DESTDIR)$(bindir)/racket@CGC_INSTALLED@"
|
||||
cd ..; cp bc/mzdyn.o "$(DESTDIR)$(libpltdir)/mzdyn.o"
|
||||
@RUN_RACKET_CGC@ $(SETUP_BOOT_COLLECTS_PATH) "$(DESTDIR)$(bindir)/racket@CGC_INSTALLED@@EXE_SUFFIX@" $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@
|
||||
$(RESTORE_SIGNATURE) "$(DESTDIR)$(bindir)/racket@CGC_INSTALLED@"
|
||||
|
||||
unix-install-libs-cgc:
|
||||
cd ..; $(ICP_LIB) bc/libmzgc.@LIBSFX@ "$(DESTDIR)$(libdir)/libmzgc.@LIBSFX@"
|
||||
|
@ -520,6 +521,7 @@ unix-install-3m:
|
|||
$(MAKE) unix-@INSTALL_LIBS_ENABLE@-libs-3m
|
||||
cd ..; $(ICP) bc/mzdyn3m.o "$(DESTDIR)$(libpltdir)/mzdyn3m.o"
|
||||
@RUN_RACKET_MMM@ $(SETUP_BOOT_COLLECTS_PATH) "$(DESTDIR)$(bindir)/racket@MMM_INSTALLED@@EXE_SUFFIX@" $(DESTDIR)@COLLECTS_PATH@ $(DESTDIR)@CONFIG_PATH@
|
||||
$(RESTORE_SIGNATURE) "$(DESTDIR)$(bindir)/racket@MMM_INSTALLED@"
|
||||
|
||||
unix-install-libs-3m:
|
||||
cd ..; $(ICP_LIB) bc/libracket3m.@LIBSFX@ "$(DESTDIR)$(libdir)/libracket3m.@LIBSFX@"
|
||||
|
@ -604,6 +606,7 @@ osx-install-cgc:
|
|||
$(MAKE) unix-install-cgc
|
||||
mkdir -p $(DESTDIR)$(MZFWDIR)/Versions/$(FWVERSION)
|
||||
cp $(MZFW) $(DESTDIR)$(MZFWDIR)/Versions/$(FWVERSION)/
|
||||
$(STRIP_SIGNATURE) $(DESTDIR)"$(bindir)/racket@CGC_INSTALLED@"
|
||||
/usr/bin/install_name_tool -change "@executable_path/Racket.framework/Versions/$(FWVERSION)/Racket" "@FRAMEWORK_PREFIX@Racket.framework/Versions/$(FWVERSION)/Racket" $(DESTDIR)"$(bindir)/racket@CGC_INSTALLED@"
|
||||
$(RESTORE_SIGNATURE) $(DESTDIR)"$(bindir)/racket@CGC_INSTALLED@"
|
||||
|
||||
|
@ -615,6 +618,7 @@ osx-install-3m:
|
|||
$(MAKE) unix-install-3m
|
||||
mkdir -p $(DESTDIR)"$(MZFWDIR)/Versions/$(FWVERSION)_3m"
|
||||
cp $(MZFWMMM) $(DESTDIR)$(MZFWDIR)/Versions/$(FWVERSION)_3m/
|
||||
$(STRIP_SIGNATURE) $(DESTDIR)"$(bindir)/racket@MMM_INSTALLED@"
|
||||
/usr/bin/install_name_tool -change "@executable_path/Racket.framework/Versions/$(FWVERSION)_3m/Racket" "@FRAMEWORK_PREFIX@Racket.framework/Versions/$(FWVERSION)_3m/Racket" $(DESTDIR)"$(bindir)/racket@MMM_INSTALLED@"
|
||||
$(RESTORE_SIGNATURE) $(DESTDIR)"$(bindir)/racket@MMM_INSTALLED@"
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ static int is_number_arg(const char *s)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if defined(OS_X) || defined(DOS_FILE_SYSTEM)
|
||||
char *add_to_str(const char *addr, long amt)
|
||||
{
|
||||
long addr_v;
|
||||
|
@ -51,23 +50,19 @@ char *add_to_str(const char *addr, long amt)
|
|||
sprintf(buf, "%ld", addr_v);
|
||||
return strdup(buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *make_embedded_load(const char *file, const char *start, const char *end)
|
||||
static char *make_embedded_load(const self_exe_t self_exe, const char *file, const char *start, const char *end)
|
||||
{
|
||||
char *s;
|
||||
int slen, elen, flen;
|
||||
|
||||
#if defined(OS_X) || defined(DOS_FILE_SYSTEM)
|
||||
if (file == NULL) {
|
||||
long fileoff;
|
||||
fileoff = get_segment_offset();
|
||||
fileoff = get_segment_offset(self_exe);
|
||||
start = add_to_str(start, fileoff);
|
||||
end = add_to_str(end, fileoff);
|
||||
file = SELF_PATH_TO_BYTES(self_exe);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!file) file = "";
|
||||
|
||||
slen = strlen(start);
|
||||
elen = strlen(end);
|
||||
|
@ -730,6 +725,7 @@ static int run_from_cmd_line(int argc, char *_argv[],
|
|||
Scheme_Object *syslog_level = NULL, *stderr_level = NULL, *stdout_level = NULL;
|
||||
FinishArgs *fa;
|
||||
FinishArgsAtoms *fa_a;
|
||||
self_exe_t self_exe;
|
||||
|
||||
scheme_set_default_locale();
|
||||
|
||||
|
@ -741,7 +737,9 @@ static int run_from_cmd_line(int argc, char *_argv[],
|
|||
console_printf = scheme_get_console_printf();
|
||||
#endif
|
||||
|
||||
extract_built_in_arguments(&prog, &sprog, &argc, &argv);
|
||||
self_exe = get_self_path(prog);
|
||||
|
||||
extract_built_in_arguments(self_exe, &prog, &sprog, &argc, &argv);
|
||||
|
||||
#ifndef DONT_PARSE_COMMAND_LINE
|
||||
evals_and_loads = (char **)malloc(sizeof(char *) * argc);
|
||||
|
@ -1024,12 +1022,12 @@ static int run_from_cmd_line(int argc, char *_argv[],
|
|||
}
|
||||
argv++;
|
||||
--argc;
|
||||
se = make_embedded_load(embedding_file, argv[0], argv[1]);
|
||||
se = make_embedded_load(self_exe, embedding_file, argv[0], argv[1]);
|
||||
evals_and_loads[num_enl] = se;
|
||||
argv++;
|
||||
--argc;
|
||||
eval_kind[num_enl++] = mzcmd_EMBEDDED_REG;
|
||||
se = make_embedded_load(embedding_file, argv[0], argv[1]);
|
||||
se = make_embedded_load(self_exe, embedding_file, argv[0], argv[1]);
|
||||
evals_and_loads[num_enl] = se;
|
||||
argv++;
|
||||
--argc;
|
||||
|
|
|
@ -60,7 +60,7 @@ MZDYNDEP = ../mzdyn.o $(srcdir)/../include/ext.exp $(srcdir)/../include/racket.e
|
|||
dynexmpl.o: $(srcdir)/dynexmpl.c $(HEADERS)
|
||||
$(PLAIN_CC) $(ALL_CFLAGS) -c $(srcdir)/dynexmpl.c -o dynexmpl.o
|
||||
|
||||
../starter@NOT_MINGW@@EXE_SUFFIX@: $(srcdir)/../../start/ustart.c $(srcdir)/../../start/unix_self.inc
|
||||
../starter@NOT_MINGW@@EXE_SUFFIX@: $(srcdir)/../../start/ustart.c $(srcdir)/../../start/self_exe.inc
|
||||
$(PLAIN_CC) $(ALL_CFLAGS) -o ../starter@EXE_SUFFIX@ $(srcdir)/../../start/ustart.c
|
||||
|
||||
PARSE_CMDL = $(srcdir)/../../start/parse_cmdl.inc
|
||||
|
|
|
@ -57,6 +57,9 @@ LDFLAGS = @LDFLAGS@
|
|||
ARLIBFLAGS = $(LDFLAGS) $(LDLIBS)
|
||||
###########################
|
||||
|
||||
STRIP_SIGNATURE = @STRIP_SIGNATURE@
|
||||
RESTORE_SIGNATURE = @RESTORE_SIGNATURE@ "${srcdir}/../../mac/entitlements.plist"
|
||||
|
||||
GRACKETLINKER = @MZLINKER@
|
||||
|
||||
LIBRKTIO = ../rktio/librktio.@LTA@
|
||||
|
@ -224,8 +227,10 @@ GRACKET_NAME@MINGW@ = GRacket
|
|||
install-wx_xt-cgc:
|
||||
$(MAKE) @MRLIBINSTALL@-cgc-wx_xt
|
||||
cd ..; $(ICP) gracket/gracket@CGC@@EXE_SUFFIX@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@"
|
||||
$(STRIP_SIGNATURE) "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@"
|
||||
cd ..; @STRIP_DEBUG@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@"
|
||||
@RUN_RACKET_CGC@ $(SETUP_BOOT_COLLECTS_PATH) @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @GUI_COLLECTS_PATH@ @GUI_CONFIG_PATH@
|
||||
$(RESTORE_SIGNATURE) "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@CGC_INSTALLED@@EXE_SUFFIX@"
|
||||
|
||||
install-wx_xt-cgc-final:
|
||||
$(NOOP)
|
||||
|
@ -239,8 +244,10 @@ install-lib-3m-wx_xt:
|
|||
install-wx_xt-3m:
|
||||
$(MAKE) @MRLIBINSTALL@-3m-wx_xt
|
||||
cd ..; $(ICP) gracket/gracket@MMM@@EXE_SUFFIX@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@"
|
||||
$(STRIP_SIGNATURE) "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@"
|
||||
cd ..; @STRIP_DEBUG@ "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@"
|
||||
@RUN_RACKET_MMM@ $(SETUP_BOOT_COLLECTS_PATH) @DIRCVTPRE@"$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@"@DIRCVTPOST@ @GUI_COLLECTS_PATH@ @GUI_CONFIG_PATH@
|
||||
$(RESTORE_SIGNATURE) "$(DESTDIR)$(libpltdir)/$(GRACKET_NAME)@MMM_INSTALLED@@EXE_SUFFIX@"
|
||||
|
||||
install-wx_xt-3m-final:
|
||||
$(NOOP)
|
||||
|
|
|
@ -32,7 +32,7 @@ EXTRA_COMPILE_DEPS =
|
|||
COMPILE_FILE = $(SCHEME) --script compile-file.ss $(UNSAFE_COMP) $(COMPRESS_COMP) $(DEBUG_COMP) $(CROSS_COMP) --dest "$(BUILDDIR)"
|
||||
COMPILE_FILE_DEPS = compile-file.ss include.ss place-register.ss $(EXTRA_COMPILE_DEPS)
|
||||
|
||||
RACKET_SETUP_ARGS = false ../../bin/racket ../../bin/racket ../collects ../etc 0 false false 0 ""
|
||||
RACKET_SETUP_ARGS = false ../../bin/racket ../../bin/racket ../collects ../etc "" 0 false false 0 ""
|
||||
|
||||
PRIMITIVES_TABLES = primitive/kernel.ss primitive/unsafe.ss primitive/flfxnum.ss \
|
||||
primitive/paramz.ss primitive/extfl.ss primitive/network.ss \
|
||||
|
|
|
@ -212,12 +212,12 @@ racket.boot: racket.so
|
|||
EMBED_DEPS = $(srcdir)/embed-boot.rkt
|
||||
|
||||
racketcs@NOT_OSX@@NOT_MINGW@: raw_racketcs petite-v.boot scheme-v.boot racket-v.boot $(EMBED_DEPS)
|
||||
$(BOOTSTRAP_RACKET) $(srcdir)/embed-boot.rkt @ELF_COMP@ --target $(TARGET_MACH) @BOOT_COMPRESS_COMP@ raw_racketcs racketcs petite-v.boot scheme-v.boot racket-v.boot
|
||||
$(BOOTSTRAP_RACKET) $(srcdir)/embed-boot.rkt --target $(TARGET_MACH) @BOOT_COMPRESS_COMP@ raw_racketcs racketcs petite-v.boot scheme-v.boot racket-v.boot
|
||||
@POST_LINKER@ racketcs
|
||||
$(RESTORE_SIGNATURE) racketcs
|
||||
|
||||
gracketcs@NOT_OSX@@NOT_MINGW@: raw_gracketcs petite-v.boot scheme-v.boot racket-v.boot $(EMBED_DEPS)
|
||||
$(BOOTSTRAP_RACKET) $(srcdir)/embed-boot.rkt @ELF_COMP@ --target $(TARGET_MACH) @BOOT_COMPRESS_COMP@ raw_gracketcs gracketcs petite-v.boot scheme-v.boot racket-v.boot
|
||||
$(BOOTSTRAP_RACKET) $(srcdir)/embed-boot.rkt --target $(TARGET_MACH) @BOOT_COMPRESS_COMP@ raw_gracketcs gracketcs petite-v.boot scheme-v.boot racket-v.boot
|
||||
@POST_LINKER@ gracketcs
|
||||
$(RESTORE_SIGNATURE) gracketcs
|
||||
|
||||
|
@ -433,7 +433,7 @@ DEF_C_DIRS = $(DEF_COLLECTS_DIR) $(DEF_CONFIG_DIR)
|
|||
|
||||
MAIN_DEPS = $(srcdir)/main.c $(srcdir)/boot.h cs_config.h \
|
||||
$(srcdir)/../../start/config.inc \
|
||||
$(srcdir)/../../start/unix_self.inc
|
||||
$(srcdir)/../../start/self_exe.inc
|
||||
|
||||
main.o: $(MAIN_DEPS)
|
||||
$(CC) $(CFLAGS) $(DEF_C_DIRS) -c -o main.o $(srcdir)/main.c
|
||||
|
@ -444,7 +444,7 @@ grmain.o: $(srcdir)/grmain.c $(MAIN_DEPS) $(srcdir)/../../start/gui_filter.inc
|
|||
boot.o: $(srcdir)/boot.c $(srcdir)/../../rktio/rktio.inc $(srcdir)/boot.h
|
||||
$(CC) $(CFLAGS) -c -o boot.o $(srcdir)/boot.c
|
||||
|
||||
starter@NOT_MINGW@: $(srcdir)/../../start/ustart.c $(srcdir)/../../start/unix_self.inc
|
||||
starter@NOT_MINGW@: $(srcdir)/../../start/ustart.c $(srcdir)/../../start/self_exe.inc
|
||||
$(CC) $(CFLAGS) -o starter $(srcdir)/../../start/ustart.c
|
||||
|
||||
|
||||
|
|
|
@ -192,9 +192,10 @@ void racket_boot(racket_boot_arguments_t *ba)
|
|||
l = Scons(Sbytevector(ba->cs_compiled_subdir ? "true" : "false"), l);
|
||||
sprintf(segment_offset_s, "%ld", ba->segment_offset);
|
||||
l = Scons(Sbytevector(segment_offset_s), l);
|
||||
l = Scons(Sbytevector(ba->k_file ? (char *)ba->k_file : (char *)ba->exec_file), l);
|
||||
l = Scons(Sbytevector(ba->config_dir ? (char *)ba->config_dir : "etc"), l);
|
||||
l = Scons(parse_coldirs(ba->collects_dir ? (char *)ba->collects_dir : ""), l);
|
||||
l = Scons(Sbytevector(ba->run_file ? (char *)ba->run_file : (char *)ba->exec_file ), l);
|
||||
l = Scons(Sbytevector(ba->run_file ? (char *)ba->run_file : (char *)ba->exec_file), l);
|
||||
l = Scons(Sbytevector((char *)ba->exec_file), l);
|
||||
l = Scons(Sbytevector(ba->exit_after ? "false" : "true"), l);
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ typedef struct racket_boot_arguments_t {
|
|||
const char *collects_dir; /* can be NULL or "" to disable collection path */
|
||||
const char *config_dir; /* use NULL or "etc" if you don't care */
|
||||
/* wchar_t * */void *dll_dir; /* can be NULL for default */
|
||||
const char *k_file; /* for -k; can be NULL for the same as `exec_file` */
|
||||
|
||||
/* How to initialize `use-compiled-file-paths`: */
|
||||
int cs_compiled_subdir; /* true => subdirectory of "compiled" */
|
||||
|
|
12
racket/src/cs/c/configure
vendored
12
racket/src/cs/c/configure
vendored
|
@ -639,7 +639,6 @@ FRAMEWORK_INSTALL_DIR
|
|||
SCHEME_CROSS_CONFIG_ARGS
|
||||
SCHEME_CONFIG_ARGS
|
||||
MAKE_BUILD_SCHEME
|
||||
ELF_COMP
|
||||
BOOT_COMPRESS_COMP
|
||||
COMPRESS_COMP
|
||||
CONFIGURE_RACKET_SO_COMPILE
|
||||
|
@ -3222,7 +3221,6 @@ NOT_MINGW=""
|
|||
CONFIGURE_RACKET_SO_COMPILE=""
|
||||
COMPRESS_COMP=""
|
||||
BOOT_COMPRESS_COMP=""
|
||||
ELF_COMP=""
|
||||
POST_LINKER="echo"
|
||||
|
||||
FRAMEWORK_INSTALL_DIR='$(libpltdir)'
|
||||
|
@ -4336,7 +4334,6 @@ case "$host_os" in
|
|||
LIBS="$LIBS -lsocket -lnsl -lintl"
|
||||
use_flag_pthread="no"
|
||||
use_flag_posix_pthread="yes"
|
||||
enable_strip=no
|
||||
;;
|
||||
aix*)
|
||||
;;
|
||||
|
@ -4347,8 +4344,6 @@ case "$host_os" in
|
|||
LIBS="${LIBS} -lm -lpthread"
|
||||
LINK_DYNAMIC="-rdynamic"
|
||||
add_iconv_lib="-liconv"
|
||||
CPPFLAGS="${CPPFLAGS} -DELF_FIND_BOOT_SECTION"
|
||||
ELF_COMP="--expect-elf"
|
||||
;;
|
||||
openbsd*)
|
||||
MACH_OS=ob
|
||||
|
@ -4358,8 +4353,6 @@ case "$host_os" in
|
|||
LINK_DYNAMIC="-Wl,--export-dynamic"
|
||||
add_iconv_lib="-liconv"
|
||||
LDFLAGS="${LDFLAGS} -Wl,-zwxneeded"
|
||||
CPPFLAGS="${CPPFLAGS} -DELF_FIND_BOOT_SECTION"
|
||||
ELF_COMP="--expect-elf"
|
||||
;;
|
||||
bitrig*)
|
||||
LINK_DYNAMIC="-Wl,--export-dynamic"
|
||||
|
@ -4372,8 +4365,6 @@ case "$host_os" in
|
|||
LIBS="${LIBS} -lm -lpthread"
|
||||
LINK_DYNAMIC="-rdynamic"
|
||||
add_iconv_lib="/usr/lib/i18n/libiconv_std.a"
|
||||
CPPFLAGS="${CPPFLAGS} -DELF_FIND_BOOT_SECTION"
|
||||
ELF_COMP="--expect-elf"
|
||||
POST_LINKER="paxctl +m"
|
||||
;;
|
||||
irix*)
|
||||
|
@ -4387,9 +4378,7 @@ case "$host_os" in
|
|||
LIBS="${LIBS} -lrt"
|
||||
;;
|
||||
esac
|
||||
CPPFLAGS="${CPPFLAGS} -DELF_FIND_BOOT_SECTION"
|
||||
LINK_DYNAMIC="-rdynamic"
|
||||
ELF_COMP="--expect-elf"
|
||||
;;
|
||||
osf1*)
|
||||
;;
|
||||
|
@ -5793,7 +5782,6 @@ SCHEME_CROSS_CONFIG_ARGS="--machine=${TARGET_MACH} --disable-x11 ${cs_auto_flags
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
makefiles="Makefile"
|
||||
|
|
|
@ -140,7 +140,6 @@ NOT_MINGW=""
|
|||
CONFIGURE_RACKET_SO_COMPILE=""
|
||||
COMPRESS_COMP=""
|
||||
BOOT_COMPRESS_COMP=""
|
||||
ELF_COMP=""
|
||||
POST_LINKER="echo"
|
||||
|
||||
FRAMEWORK_INSTALL_DIR='$(libpltdir)'
|
||||
|
@ -218,7 +217,6 @@ case "$host_os" in
|
|||
LIBS="$LIBS -lsocket -lnsl -lintl"
|
||||
use_flag_pthread="no"
|
||||
use_flag_posix_pthread="yes"
|
||||
enable_strip=no
|
||||
;;
|
||||
aix*)
|
||||
;;
|
||||
|
@ -229,8 +227,6 @@ case "$host_os" in
|
|||
LIBS="${LIBS} -lm -lpthread"
|
||||
LINK_DYNAMIC="-rdynamic"
|
||||
add_iconv_lib="-liconv"
|
||||
CPPFLAGS="${CPPFLAGS} -DELF_FIND_BOOT_SECTION"
|
||||
ELF_COMP="--expect-elf"
|
||||
;;
|
||||
openbsd*)
|
||||
MACH_OS=ob
|
||||
|
@ -240,8 +236,6 @@ case "$host_os" in
|
|||
LINK_DYNAMIC="-Wl,--export-dynamic"
|
||||
add_iconv_lib="-liconv"
|
||||
LDFLAGS="${LDFLAGS} -Wl,-zwxneeded"
|
||||
CPPFLAGS="${CPPFLAGS} -DELF_FIND_BOOT_SECTION"
|
||||
ELF_COMP="--expect-elf"
|
||||
;;
|
||||
bitrig*)
|
||||
LINK_DYNAMIC="-Wl,--export-dynamic"
|
||||
|
@ -254,8 +248,6 @@ case "$host_os" in
|
|||
LIBS="${LIBS} -lm -lpthread"
|
||||
LINK_DYNAMIC="-rdynamic"
|
||||
add_iconv_lib="/usr/lib/i18n/libiconv_std.a"
|
||||
CPPFLAGS="${CPPFLAGS} -DELF_FIND_BOOT_SECTION"
|
||||
ELF_COMP="--expect-elf"
|
||||
POST_LINKER="paxctl +m"
|
||||
;;
|
||||
irix*)
|
||||
|
@ -269,9 +261,7 @@ case "$host_os" in
|
|||
LIBS="${LIBS} -lrt"
|
||||
;;
|
||||
esac
|
||||
CPPFLAGS="${CPPFLAGS} -DELF_FIND_BOOT_SECTION"
|
||||
LINK_DYNAMIC="-rdynamic"
|
||||
ELF_COMP="--expect-elf"
|
||||
;;
|
||||
osf1*)
|
||||
;;
|
||||
|
@ -819,7 +809,6 @@ AC_SUBST(LZ4_LIB_UNPACK)
|
|||
AC_SUBST(CONFIGURE_RACKET_SO_COMPILE)
|
||||
AC_SUBST(COMPRESS_COMP)
|
||||
AC_SUBST(BOOT_COMPRESS_COMP)
|
||||
AC_SUBST(ELF_COMP)
|
||||
AC_SUBST(MAKE_BUILD_SCHEME)
|
||||
AC_SUBST(SCHEME_CONFIG_ARGS)
|
||||
AC_SUBST(SCHEME_CROSS_CONFIG_ARGS)
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
compiler/private/elf
|
||||
"adjust-compress.rkt")
|
||||
|
||||
(define expect-elf? #f)
|
||||
(define alt-dests '())
|
||||
(define target #f)
|
||||
|
||||
|
@ -14,8 +13,6 @@
|
|||
#:once-each
|
||||
[("--compress") "Leave compiled code files as compressed"
|
||||
(enable-compress!)]
|
||||
[("--expect-elf") "Record offset from ELF section"
|
||||
(set! expect-elf? #t)]
|
||||
[("--target") machine "Select target machine"
|
||||
(set! target machine)]
|
||||
#:multi
|
||||
|
@ -57,7 +54,10 @@
|
|||
"x86_64-darwin" "i386-darwin" "aarch64-darwin"
|
||||
"x86_64-macosx" "i386-macosx" "aarch64-macosx")
|
||||
;; Mach-O
|
||||
(copy-file use-src-file dest-file #t)
|
||||
(when (file-exists? dest-file)
|
||||
;; explicit delete to avoid signature unhappiness
|
||||
(delete-file dest-file))
|
||||
(copy-file use-src-file dest-file)
|
||||
(remove-signature dest-file)
|
||||
(add-plt-segment dest-file data #:name #"__RKTBOOT")
|
||||
;; Find segment at run time:
|
||||
|
@ -86,12 +86,8 @@
|
|||
[start-pos
|
||||
;; Success as ELF
|
||||
(file-or-directory-permissions dest-file (file-or-directory-permissions use-src-file 'bits))
|
||||
(cond
|
||||
[expect-elf?
|
||||
;; Find ".rackboot" at run time:
|
||||
0]
|
||||
[else
|
||||
start-pos])]
|
||||
;; Find ".rackboot" at run time:
|
||||
0]
|
||||
[else
|
||||
;; Not ELF; just append to the end
|
||||
(copy-file use-src-file dest-file #t)
|
||||
|
@ -102,8 +98,6 @@
|
|||
(lambda (o)
|
||||
(file-position o pos)
|
||||
(write-bytes data o)))
|
||||
(when expect-elf?
|
||||
(error 'embed-boot "expected ELF"))
|
||||
pos])]))
|
||||
|
||||
(define (write-offsets dest-file)
|
||||
|
|
|
@ -57,34 +57,11 @@ PRESERVE_IN_EXECUTABLE
|
|||
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;
|
||||
|
||||
#include "../../start/unix_self.inc"
|
||||
|
||||
#ifdef OS_X
|
||||
# include <mach-o/dyld.h>
|
||||
static long find_rktboot_section(char *me)
|
||||
{
|
||||
const struct mach_header *mh;
|
||||
const struct load_command *lc;
|
||||
int i;
|
||||
|
||||
mh = _dyld_get_image_header(0);
|
||||
|
||||
lc = (void *)((char *)mh + ((mh->magic == 0xfeedfacf) ? sizeof(struct mach_header_64) : sizeof(struct mach_header)));
|
||||
|
||||
for (i = 0; i < mh->ncmds; i++) {
|
||||
if (lc->cmd == LC_SEGMENT) {
|
||||
const struct segment_command *sc = (struct segment_command *)lc;
|
||||
if (!strcmp(sc->segname, "__RKTBOOT"))
|
||||
return sc->fileoff;
|
||||
} else if (lc->cmd == LC_SEGMENT_64) {
|
||||
const struct segment_command_64 *sc = (struct segment_command_64 *)lc;
|
||||
if (!strcmp(sc->segname, "__RKTBOOT"))
|
||||
return sc->fileoff;
|
||||
}
|
||||
lc = (void *)((char *)lc + lc->cmdsize);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return find_mach_o_segment("__RKTBOOT", NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -127,69 +104,18 @@ static char *path_append(const char *p1, char *p2) {
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef ELF_FIND_BOOT_SECTION
|
||||
# include <elf.h>
|
||||
# include <fcntl.h>
|
||||
|
||||
static long find_boot_section(char *me)
|
||||
#if !defined(WIN32) && !defined(OS_X)
|
||||
static long find_boot_section(const char *me)
|
||||
{
|
||||
int fd, i;
|
||||
#if SIZEOF_VOID_P == 4
|
||||
Elf32_Ehdr e;
|
||||
Elf32_Shdr s;
|
||||
#else
|
||||
Elf64_Ehdr e;
|
||||
Elf64_Shdr s;
|
||||
#endif
|
||||
char *strs;
|
||||
int start = 0, end = 0;
|
||||
|
||||
fd = open(me, O_RDONLY, 0);
|
||||
if (fd == -1) return 0;
|
||||
find_elf_section_offset(me, ".rackboot", &start, &end);
|
||||
|
||||
if (read(fd, &e, sizeof(e)) == sizeof(e)) {
|
||||
lseek(fd, e.e_shoff + (e.e_shstrndx * e.e_shentsize), SEEK_SET);
|
||||
if (read(fd, &s, sizeof(s)) != sizeof(s)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strs = (char *)malloc(s.sh_size);
|
||||
lseek(fd, s.sh_offset, SEEK_SET);
|
||||
if (read(fd, strs, s.sh_size) != s.sh_size) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < e.e_shnum; i++) {
|
||||
lseek(fd, e.e_shoff + (i * e.e_shentsize), SEEK_SET);
|
||||
if (read(fd, &s, sizeof(s)) != sizeof(s)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(strs + s.sh_name, ".rackboot")) {
|
||||
close(fd);
|
||||
return s.sh_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
return start;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
static char *string_to_utf8(wchar_t *p)
|
||||
{
|
||||
char *r;
|
||||
int len;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, p, -1, NULL, 0, NULL, NULL);
|
||||
r = malloc(len);
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, p, -1, r, len, NULL, NULL);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int scheme_utf8_encode(unsigned int *path, int zero_offset, int len,
|
||||
char *dest, int offset, int get_utf16)
|
||||
|
@ -202,126 +128,6 @@ static int scheme_utf8_encode(unsigned int *path, int zero_offset, int len,
|
|||
}
|
||||
|
||||
# include "../start/cmdl_to_argv.inc"
|
||||
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
||||
|
||||
#ifdef USE_GENERIC_GET_SELF_PATH
|
||||
/* Get executable path via argv[0] and the `PATH` environment variable */
|
||||
|
||||
static int has_slash(char *s)
|
||||
{
|
||||
while (*s) {
|
||||
if (s[0] == '/')
|
||||
return 1;
|
||||
s++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *do_path_append(char *s1, int l1, char *s2)
|
||||
{
|
||||
int l2;
|
||||
char *s;
|
||||
|
||||
l2 = strlen(s2);
|
||||
|
||||
s = (char *)malloc(l1 + l2 + 2);
|
||||
|
||||
memcpy(s, s1, l1);
|
||||
if (s[l1 - 1] != '/') {
|
||||
s[l1++] = '/';
|
||||
}
|
||||
|
||||
memcpy(s + l1, s2, l2);
|
||||
s[l1 + l2] = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static char *path_append(char *s1, char *s2)
|
||||
{
|
||||
return do_path_append(s1, strlen(s1), s2);
|
||||
}
|
||||
|
||||
static char *copy_string(char *s1)
|
||||
{
|
||||
int l1;
|
||||
char *s;
|
||||
|
||||
if (!s1) return NULL;
|
||||
|
||||
l1 = strlen(s1);
|
||||
|
||||
s = (char *)malloc(l1 + 1);
|
||||
|
||||
memcpy(s, s1, l1 + 1);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static int executable_exists(char *path)
|
||||
{
|
||||
return (access(path, X_OK) == 0);
|
||||
}
|
||||
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
if (exec_file[0] == '/') {
|
||||
/* Absolute path */
|
||||
return exec_file;
|
||||
} else if (has_slash(exec_file)) {
|
||||
/* Relative path with a directory: */
|
||||
char *buf;
|
||||
long buflen = 4096;
|
||||
buf = (char *)malloc(buflen);
|
||||
return path_append(getcwd(buf, buflen), exec_file);
|
||||
} else {
|
||||
/* We have to find the executable by searching PATH: */
|
||||
char *path = copy_string(getenv("PATH")), *p, *m;
|
||||
int more;
|
||||
|
||||
if (!path) {
|
||||
path = "";
|
||||
}
|
||||
|
||||
while (1) {
|
||||
/* Try each element of path: */
|
||||
for (p = path; *p && (*p != ':'); p++) { }
|
||||
if (*p) {
|
||||
*p = 0;
|
||||
more = 1;
|
||||
} else
|
||||
more = 0;
|
||||
|
||||
if (!*path)
|
||||
break;
|
||||
|
||||
m = path_append(path, exec_file);
|
||||
|
||||
if (executable_exists(m)) {
|
||||
if (m[0] != '/')
|
||||
m = path_append(getcwd(NULL, 0), m);
|
||||
return m;
|
||||
}
|
||||
free(m);
|
||||
|
||||
if (more)
|
||||
path = p + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return exec_file;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NO_GET_SEGMENT_OFFSET
|
||||
static long get_segment_offset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
|
@ -355,6 +161,7 @@ static int bytes_main(int argc, char **argv,
|
|||
int wm_is_gracket_or_x11_arg_count, char *gracket_guid_or_x11_args)
|
||||
{
|
||||
char *boot_exe;
|
||||
self_exe_t self_exe;
|
||||
char *exec_file = argv[0], *run_file = NULL;
|
||||
char *boot1_path, *boot2_path, *boot3_path;
|
||||
int boot1_offset, boot2_offset, boot3_offset, boot_end_offset;
|
||||
|
@ -374,12 +181,12 @@ static int bytes_main(int argc, char **argv,
|
|||
argv++;
|
||||
}
|
||||
|
||||
extract_built_in_arguments(&exec_file, &run_file, &argc, &argv);
|
||||
self_exe = get_self_path(exec_file);
|
||||
|
||||
extract_built_in_arguments(self_exe, &exec_file, &run_file, &argc, &argv);
|
||||
if (!run_file)
|
||||
run_file = exec_file;
|
||||
|
||||
segment_offset = get_segment_offset();
|
||||
|
||||
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));
|
||||
|
@ -393,7 +200,7 @@ static int bytes_main(int argc, char **argv,
|
|||
dll = embedded_dll_open("libracketcsxxxxxxx.dll", 1);
|
||||
boot_rsrc_offset = in_memory_get_offset("libracketcsxxxxxxx.dll");
|
||||
racket_boot_p = (racket_boot_t)scheme_dll_find_object(dll, "racket_boot");
|
||||
dll_path = get_self_executable_path();
|
||||
dll_path = self_exe;
|
||||
} else {
|
||||
HMODULE dll;
|
||||
dll_path = load_delayed_dll_x(NULL, "libracketcsxxxxxxx.dll", &dll);
|
||||
|
@ -402,18 +209,19 @@ static int bytes_main(int argc, char **argv,
|
|||
boot_exe = string_to_utf8(dll_path);
|
||||
# define racket_boot racket_boot_p
|
||||
#else
|
||||
boot_exe = get_self_path(exec_file);
|
||||
boot_exe = self_exe;
|
||||
#endif
|
||||
|
||||
#ifdef ELF_FIND_BOOT_SECTION
|
||||
boot_offset = find_boot_section(boot_exe);
|
||||
#elif defined(OS_X)
|
||||
/* segment_offset is for embedded bytecode (not boot files) */
|
||||
segment_offset = get_segment_offset(self_exe);
|
||||
|
||||
#if defined(OS_X)
|
||||
boot_offset = find_rktboot_section(boot_exe);
|
||||
if (!boot_offset) boot_images_in_exe = 0;
|
||||
#elif WIN32
|
||||
boot_offset = find_resource_offset(dll_path, 259, boot_rsrc_offset);
|
||||
#else
|
||||
boot_offset = 0;
|
||||
boot_offset = find_boot_section(boot_exe);
|
||||
#endif
|
||||
|
||||
boot1_offset += boot_offset;
|
||||
|
@ -470,6 +278,7 @@ static int bytes_main(int argc, char **argv,
|
|||
ba.collects_dir = extract_coldir();
|
||||
ba.config_dir = extract_configdir();
|
||||
ba.dll_dir = extract_dlldir();
|
||||
ba.k_file = SELF_PATH_TO_BYTES(self_exe);
|
||||
|
||||
ba.cs_compiled_subdir = CS_COMPILED_SUBDIR;
|
||||
|
||||
|
|
|
@ -86,13 +86,13 @@
|
|||
(#%newline (#%current-error-port))
|
||||
(exit 1))
|
||||
|
||||
(define builtin-argc 10)
|
||||
(define builtin-argc 11)
|
||||
(seq
|
||||
(unless (>= (length the-command-line-arguments) builtin-argc)
|
||||
(startup-error (string-append
|
||||
"expected `embedded-interactive-mode?`,"
|
||||
" `exec-file`, `run-file`, `collects`, and `etc` paths"
|
||||
" plus `segment-offset`, `cs-compiled-subdir?`, `is-gui?`,"
|
||||
" plus `k-file`, `segment-offset`, `cs-compiled-subdir?`, `is-gui?`,"
|
||||
" `wm-is-gracket-or-x11-arg-count`, and `gracket-guid-or-x11-args`"
|
||||
" to start")))
|
||||
(set-exec-file! (->path (list-ref the-command-line-arguments/maybe-bytes 1)))
|
||||
|
@ -110,11 +110,14 @@
|
|||
(map ->path (cdr s))))])))
|
||||
(define init-config-dir (->path (or (getenv-bytes "PLTCONFIGDIR")
|
||||
(list-ref the-command-line-arguments/maybe-bytes 4))))
|
||||
(define segment-offset (#%string->number (list-ref the-command-line-arguments 5)))
|
||||
(define cs-compiled-subdir? (string=? "true" (list-ref the-command-line-arguments 6)))
|
||||
(define gracket? (string=? "true" (list-ref the-command-line-arguments 7)))
|
||||
(define wm-is-gracket-or-x11-arg-count (string->number (list-ref the-command-line-arguments 8)))
|
||||
(define gracket-guid-or-x11-args (list-ref the-command-line-arguments 9))
|
||||
(define k-executable-path (let ([s (list-ref the-command-line-arguments/maybe-bytes 5)])
|
||||
(and (not (or (equal? s "") (equal? s '#vu8())))
|
||||
s)))
|
||||
(define segment-offset (#%string->number (list-ref the-command-line-arguments 6)))
|
||||
(define cs-compiled-subdir? (string=? "true" (list-ref the-command-line-arguments 7)))
|
||||
(define gracket? (string=? "true" (list-ref the-command-line-arguments 8)))
|
||||
(define wm-is-gracket-or-x11-arg-count (string->number (list-ref the-command-line-arguments 9)))
|
||||
(define gracket-guid-or-x11-args (list-ref the-command-line-arguments 10))
|
||||
|
||||
(seq
|
||||
(when (eq? 'windows (system-type))
|
||||
|
@ -415,10 +418,11 @@
|
|||
(let ([n (#%string->number s)])
|
||||
(unless (exact-integer? n)
|
||||
(startup-error "bad ~a: ~a" what s))
|
||||
(#%number->string (+ n segment-offset))))]
|
||||
(#%number->string (+ n (if f 0 segment-offset)))))]
|
||||
[n (add-segment-offset n "starting offset")]
|
||||
[m (add-segment-offset m "first ending offset")]
|
||||
[p (add-segment-offset p "second ending offset")])
|
||||
[p (add-segment-offset p "second ending offset")]
|
||||
[f (or f k-executable-path)])
|
||||
(set! loads
|
||||
(cons
|
||||
(lambda ()
|
||||
|
|
|
@ -1,5 +1,36 @@
|
|||
/* This code fragment embeds strings in an executable that can be
|
||||
updated with various Racket exe-manipulation tools. */
|
||||
updated with various Racket exe-manipulation tools.
|
||||
|
||||
Used by CS's "main.c" and BC's "cmdline.inc".
|
||||
|
||||
Functions that are "exported":
|
||||
|
||||
self_exe_t get_self_path(char *argv0);
|
||||
void extract_built_in_arguments(const self_exe_t self_exe,
|
||||
char **_prog, char **_sprog,
|
||||
int *_argc, char ***_argv);
|
||||
char *SELF_PATH_TO_BYTES(self_exe_t)
|
||||
|
||||
char *extract_coldir();
|
||||
char *extract_configdir();
|
||||
|
||||
long get_segment_offset(self_exe_t self); // added to `-k` arguments
|
||||
|
||||
Windows:
|
||||
self_exe_t is wchar_t
|
||||
wchar_t *extract_dlldir();
|
||||
long find_resource_offset(const wchar_t *path, int id, long delta);
|
||||
char *string_to_utf8(wchar_t *p);
|
||||
|
||||
Mac OS:
|
||||
long find_mach_o_segment(const char *name, long *_len);
|
||||
|
||||
Unix:
|
||||
int find_elf_section_offset(const char *filename,
|
||||
const char *name,
|
||||
int *_start, int *_end);
|
||||
|
||||
*/
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
|
||||
|
@ -99,15 +130,19 @@ static int _configdir_offset = 17; /* Skip permanent tag */
|
|||
# define XFORM_OK_PLUS +
|
||||
#endif
|
||||
|
||||
#ifdef OS_X
|
||||
# include <mach-o/getsect.h>
|
||||
# include <mach-o/dyld.h>
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef DOS_FILE_SYSTEM
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <errno.h>
|
||||
# include <fcntl.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/uio.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "self_exe.inc"
|
||||
|
||||
#ifdef DOS_FILE_SYSTEM
|
||||
#ifndef DLL_RELATIVE_PATH
|
||||
# define DLL_RELATIVE_PATH L"lib"
|
||||
#endif
|
||||
|
@ -127,40 +162,13 @@ END_XFORM_SKIP;
|
|||
#endif
|
||||
|
||||
#ifdef OS_X
|
||||
static long get_segment_offset()
|
||||
static long get_segment_offset(const char *me)
|
||||
{
|
||||
# if defined(__x86_64__) || defined(__arm64__)
|
||||
const struct segment_command_64 *seg;
|
||||
# else
|
||||
const struct segment_command *seg;
|
||||
#endif
|
||||
seg = getsegbyname("__PLTSCHEME");
|
||||
if (seg)
|
||||
return seg->fileoff;
|
||||
else
|
||||
return 0;
|
||||
return find_mach_o_segment("__PLTSCHEME", NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DOS_FILE_SYSTEM
|
||||
wchar_t *get_self_executable_path() XFORM_SKIP_PROC
|
||||
{
|
||||
wchar_t *path;
|
||||
DWORD r, sz = 1024;
|
||||
|
||||
while (1) {
|
||||
path = (wchar_t *)malloc(sz * sizeof(wchar_t));
|
||||
r = GetModuleFileNameW(NULL, path, sz);
|
||||
if ((r == sz)
|
||||
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
|
||||
free(path);
|
||||
sz = 2 * sz;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static DWORD find_by_id(HANDLE fd, DWORD rsrcs, DWORD pos, int id, long delta) XFORM_SKIP_PROC
|
||||
{
|
||||
|
@ -185,7 +193,7 @@ static DWORD find_by_id(HANDLE fd, DWORD rsrcs, DWORD pos, int id, long delta) X
|
|||
return 0;
|
||||
}
|
||||
|
||||
static long find_resource_offset(wchar_t *path, int id, long delta) XFORM_SKIP_PROC
|
||||
static long find_resource_offset(const wchar_t *path, int id, long delta) XFORM_SKIP_PROC
|
||||
{
|
||||
/* Find the resource of type `id` */
|
||||
HANDLE fd;
|
||||
|
@ -258,14 +266,45 @@ static long find_resource_offset(wchar_t *path, int id, long delta) XFORM_SKIP_P
|
|||
}
|
||||
}
|
||||
|
||||
static long get_segment_offset() XFORM_SKIP_PROC
|
||||
static long get_segment_offset(const wchar_t *me) XFORM_SKIP_PROC
|
||||
{
|
||||
return find_resource_offset(get_self_executable_path(), 257, 0);
|
||||
return find_resource_offset(me, 257, 0);
|
||||
}
|
||||
|
||||
static char *string_to_utf8(wchar_t *p) XFORM_SKIP_PROC
|
||||
{
|
||||
char *r;
|
||||
int len;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, p, -1, NULL, 0, NULL, NULL);
|
||||
r = malloc(len);
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, p, -1, r, len, NULL, NULL);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
# define SELF_PATH_TO_BYTES(s) string_to_utf8(s)
|
||||
|
||||
#else
|
||||
|
||||
# define SELF_PATH_TO_BYTES(s) s
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(OS_X) && !defined(DOS_FILE_SYSTEM)
|
||||
|
||||
static long get_segment_offset(const char *me) XFORM_SKIP_PROC
|
||||
{
|
||||
int start = 0, end = 0;
|
||||
|
||||
(void)find_elf_section_offset(me, ".rackprog", &start, &end);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void extract_built_in_arguments(char **_prog, char **_sprog, int *_argc, char ***_argv)
|
||||
static void extract_built_in_arguments(const self_exe_t self_exe, char **_prog, char **_sprog, int *_argc, char ***_argv)
|
||||
{
|
||||
GC_CAN_IGNORE char *prog = *_prog;
|
||||
GC_CAN_IGNORE char *sprog = *_sprog;
|
||||
|
@ -321,9 +360,8 @@ static void extract_built_in_arguments(char **_prog, char **_sprog, int *_argc,
|
|||
the cmdline string is. It might be relative to the
|
||||
executable. */
|
||||
HANDLE fd;
|
||||
wchar_t *path;
|
||||
wchar_t *path = self_exe;
|
||||
|
||||
path = get_self_executable_path();
|
||||
fd = CreateFileW(path, GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
|
@ -337,7 +375,7 @@ static void extract_built_in_arguments(char **_prog, char **_sprog, int *_argc,
|
|||
DWORD got;
|
||||
start = *(long *)&scheme_cmdline_exe_hack[4];
|
||||
len = *(long *)&scheme_cmdline_exe_hack[8];
|
||||
start += get_segment_offset();
|
||||
start += get_segment_offset(self_exe);
|
||||
p = (unsigned char *)malloc(len);
|
||||
SetFilePointer(fd, start, 0, FILE_BEGIN);
|
||||
ReadFile(fd, p, len, &got, NULL);
|
||||
|
@ -386,14 +424,12 @@ static void extract_built_in_arguments(char **_prog, char **_sprog, int *_argc,
|
|||
+ 4);
|
||||
}
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
#endif
|
||||
#if defined(OS_X)
|
||||
#else
|
||||
if (scheme_cmdline_exe_hack[0] == '?') {
|
||||
long fileoff, cmdoff, cmdlen;
|
||||
long fileoff, cmdoff, cmdlen, need, got;
|
||||
int fd;
|
||||
fileoff = get_segment_offset();
|
||||
fileoff = get_segment_offset(self_exe);
|
||||
|
||||
p = (unsigned char *)scheme_cmdline_exe_hack + 4;
|
||||
cmdoff = (p[0]
|
||||
|
@ -406,9 +442,17 @@ static void extract_built_in_arguments(char **_prog, char **_sprog, int *_argc,
|
|||
+ (((long)p[7]) << 24));
|
||||
p = malloc(cmdlen);
|
||||
|
||||
fd = open(_dyld_get_image_name(0), O_RDONLY);
|
||||
fd = open(self_exe, O_RDONLY);
|
||||
lseek(fd, fileoff + cmdoff, 0);
|
||||
read(fd, p, cmdlen);
|
||||
|
||||
for (need = cmdlen; need > 0; need -= got) {
|
||||
got = read(fd, p + (cmdlen - need), need);
|
||||
if (got == -1) {
|
||||
got = 0;
|
||||
if (errno != EINTR)
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
|
@ -465,7 +509,3 @@ static char *extract_configdir()
|
|||
{
|
||||
return scheme_configdir XFORM_OK_PLUS _configdir_offset;
|
||||
}
|
||||
|
||||
#if !defined(OS_X) && !defined(DOS_FILE_SYSTEM)
|
||||
# define NO_GET_SEGMENT_OFFSET
|
||||
#endif
|
||||
|
|
|
@ -20,7 +20,7 @@ static HANDLE open_self()
|
|||
wchar_t *path;
|
||||
HANDLE fd;
|
||||
|
||||
path = get_self_executable_path();
|
||||
path = get_self_path(NULL);
|
||||
|
||||
fd = CreateFileW(path, GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
|
@ -38,7 +38,7 @@ static void parse_embedded_dlls()
|
|||
{
|
||||
long rsrc_pos;
|
||||
|
||||
rsrc_pos = find_resource_offset(get_self_executable_path(), 258, 0);
|
||||
rsrc_pos = find_resource_offset(get_self_path(NULL), 258, 0);
|
||||
if (rsrc_pos) {
|
||||
HANDLE fd = open_self();
|
||||
|
||||
|
|
368
racket/src/start/self_exe.inc
Normal file
368
racket/src/start/self_exe.inc
Normal file
|
@ -0,0 +1,368 @@
|
|||
/* Used by "ustart.c" and "config.inc".
|
||||
|
||||
Defines self_exe_t get_self_path(char *exec_file),
|
||||
which takes argv[0] and returns an improved representation of
|
||||
the containing executable. At worst, on Unix, uses `PATH` to
|
||||
convert `exec_file` into a path.
|
||||
|
||||
On Mac (even XonX), `find_mach_o_segment` is also defined.
|
||||
|
||||
On Unix (not Mac OS, not even XonX), `find_elf_section`
|
||||
is also defined.
|
||||
|
||||
If USE_EXE_LOOKUP_VIA_PATH, also: `lookup_exe_via_path`,
|
||||
`path_append`, and `do_path_append`.
|
||||
*/
|
||||
|
||||
#define USE_GENERIC_GET_SELF_PATH
|
||||
|
||||
#ifdef DOS_FILE_SYSTEM
|
||||
typedef wchar_t *self_exe_t;
|
||||
#else
|
||||
typedef char *self_exe_t;
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
# include <errno.h>
|
||||
# include <unistd.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
char buf[256], *s = buf;
|
||||
ssize_t len, blen = sizeof(buf);
|
||||
|
||||
while (1) {
|
||||
len = readlink("/proc/self/exe", s, blen-1);
|
||||
if (len == (blen-1)) {
|
||||
if (s != buf) free(s);
|
||||
blen *= 2;
|
||||
s = malloc(blen);
|
||||
} else if (len < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
buf[len] = 0;
|
||||
return strdup(buf);
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
# include <sys/sysctl.h>
|
||||
# include <errno.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
int mib[4];
|
||||
char *s;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
#if defined(__NetBSD__)
|
||||
mib[1] = KERN_PROC_ARGS;
|
||||
mib[2] = getpid();
|
||||
mib[3] = KERN_PROC_PATHNAME;
|
||||
#else
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PATHNAME;
|
||||
mib[3] = -1;
|
||||
#endif
|
||||
|
||||
r = sysctl(mib, 4, NULL, &len, NULL, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
s = malloc(len);
|
||||
r = sysctl(mib, 4, s, &len, NULL, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
# include <mach-o/getsect.h>
|
||||
# include <mach-o/dyld.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
char buf[1024], *s;
|
||||
uint32_t size = sizeof(buf);
|
||||
int r;
|
||||
|
||||
r = _NSGetExecutablePath(buf, &size);
|
||||
if (!r)
|
||||
return strdup(buf);
|
||||
else {
|
||||
s = malloc(size);
|
||||
r = _NSGetExecutablePath(s, &size);
|
||||
if (!r)
|
||||
return s;
|
||||
fprintf(stderr, "failed to get self\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
|
||||
static long find_mach_o_segment(const char *name, long *_len)
|
||||
{
|
||||
# if defined(__x86_64__) || defined(__arm64__)
|
||||
const struct segment_command_64 *seg;
|
||||
# else
|
||||
const struct segment_command *seg;
|
||||
#endif
|
||||
seg = getsegbyname(name);
|
||||
if (seg) {
|
||||
if (_len)
|
||||
*_len = seg->filesize;
|
||||
return seg->fileoff;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DOS_FILE_SYSTEM
|
||||
/* used outside this file: */
|
||||
wchar_t *get_self_path(char *exec_file) XFORM_SKIP_PROC
|
||||
{
|
||||
wchar_t *path;
|
||||
DWORD r, sz = 1024;
|
||||
|
||||
while (1) {
|
||||
path = (wchar_t *)malloc(sz * sizeof(wchar_t));
|
||||
r = GetModuleFileNameW(NULL, path, sz);
|
||||
if ((r == sz)
|
||||
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
|
||||
free(path);
|
||||
sz = 2 * sz;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
||||
|
||||
#if defined(USE_GENERIC_GET_SELF_PATH) || defined(USE_EXE_LOOKUP_VIA_PATH)
|
||||
|
||||
/* Get executable path via argv[0] and the `PATH` environment variable */
|
||||
|
||||
static int has_slash(char *s) XFORM_SKIP_PROC
|
||||
{
|
||||
while (*s) {
|
||||
if (s[0] == '/')
|
||||
return 1;
|
||||
s++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *do_path_append(char *s1, int l1, char *s2) XFORM_SKIP_PROC
|
||||
{
|
||||
int l2;
|
||||
char *s;
|
||||
|
||||
l2 = strlen(s2);
|
||||
|
||||
s = (char *)malloc(l1 + l2 + 2);
|
||||
|
||||
memcpy(s, s1, l1);
|
||||
if (s[l1 - 1] != '/') {
|
||||
s[l1++] = '/';
|
||||
}
|
||||
|
||||
memcpy(s + l1, s2, l2);
|
||||
s[l1 + l2] = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static char *path_append(char *s1, char *s2) XFORM_SKIP_PROC
|
||||
{
|
||||
return do_path_append(s1, strlen(s1), s2);
|
||||
}
|
||||
|
||||
static char *copy_string(char *s1) XFORM_SKIP_PROC
|
||||
{
|
||||
int l1;
|
||||
char *s;
|
||||
|
||||
if (!s1) return NULL;
|
||||
|
||||
l1 = strlen(s1);
|
||||
|
||||
s = (char *)malloc(l1 + 1);
|
||||
|
||||
memcpy(s, s1, l1 + 1);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static int executable_exists(char *path) XFORM_SKIP_PROC
|
||||
{
|
||||
return (access(path, X_OK) == 0);
|
||||
}
|
||||
|
||||
static char *lookup_exe_via_path(char *exec_file) XFORM_SKIP_PROC
|
||||
{
|
||||
if (exec_file[0] == '/') {
|
||||
/* Absolute path */
|
||||
return exec_file;
|
||||
} else if (has_slash(exec_file)) {
|
||||
/* Relative path with a directory: */
|
||||
char *buf;
|
||||
long buflen = 4096;
|
||||
buf = (char *)malloc(buflen);
|
||||
return path_append(getcwd(buf, buflen), exec_file);
|
||||
} else {
|
||||
/* We have to find the executable by searching PATH: */
|
||||
char *path = copy_string(getenv("PATH")), *p, *m;
|
||||
int more;
|
||||
|
||||
if (!path) {
|
||||
path = "";
|
||||
}
|
||||
|
||||
while (1) {
|
||||
/* Try each element of path: */
|
||||
for (p = path; *p && (*p != ':'); p++) { }
|
||||
if (*p) {
|
||||
*p = 0;
|
||||
more = 1;
|
||||
} else
|
||||
more = 0;
|
||||
|
||||
if (!*path)
|
||||
break;
|
||||
|
||||
m = path_append(path, exec_file);
|
||||
|
||||
if (executable_exists(m)) {
|
||||
if (m[0] != '/')
|
||||
m = path_append(getcwd(NULL, 0), m);
|
||||
return m;
|
||||
}
|
||||
free(m);
|
||||
|
||||
if (more)
|
||||
path = p + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return exec_file;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_GENERIC_GET_SELF_PATH
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
return lookup_exe_via_path(exec_file);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(OS_X) && !defined(DOS_FILE_SYSTEM)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
typedef unsigned short ELF__Half;
|
||||
typedef unsigned int ELF__Word;
|
||||
typedef unsigned long ELF__Xword;
|
||||
typedef unsigned long ELF__Addr;
|
||||
typedef unsigned long ELF__Off;
|
||||
|
||||
typedef struct {
|
||||
unsigned char e_ident[16];
|
||||
ELF__Half e_type;
|
||||
ELF__Half e_machine;
|
||||
ELF__Word e_version;
|
||||
ELF__Addr e_entry;
|
||||
ELF__Off e_phoff;
|
||||
ELF__Off e_shoff;
|
||||
ELF__Word e_flags;
|
||||
ELF__Half e_ehsize;
|
||||
ELF__Half e_phentsize;
|
||||
ELF__Half e_phnum;
|
||||
ELF__Half e_shentsize;
|
||||
ELF__Half e_shnum;
|
||||
ELF__Half e_shstrndx;
|
||||
} ELF__Header;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ELF__Word sh_name;
|
||||
ELF__Word sh_type;
|
||||
ELF__Xword sh_flags;
|
||||
ELF__Addr sh_addr;
|
||||
ELF__Off sh_offset;
|
||||
ELF__Xword sh_size;
|
||||
ELF__Word sh_link;
|
||||
ELF__Word sh_info;
|
||||
ELF__Xword sh_addralign;
|
||||
ELF__Xword sh_entsize;
|
||||
} Elf__Shdr;
|
||||
|
||||
static int find_elf_section_offset(const char *filename,
|
||||
const char *name,
|
||||
int *_start, int *_end) XFORM_SKIP_PROC
|
||||
{
|
||||
int fd, i;
|
||||
ELF__Header e;
|
||||
Elf__Shdr s;
|
||||
char *strs;
|
||||
|
||||
fd = open(filename, O_RDONLY, 0);
|
||||
if (fd == -1) return 0;
|
||||
|
||||
if (read(fd, &e, sizeof(e)) == sizeof(e)) {
|
||||
if ((e.e_ident[0] == 0x7F)
|
||||
&& (e.e_ident[1] == 'E')
|
||||
&& (e.e_ident[2] == 'L')
|
||||
&& (e.e_ident[3] == 'F')) {
|
||||
|
||||
lseek(fd, e.e_shoff + (e.e_shstrndx * e.e_shentsize), SEEK_SET);
|
||||
if (read(fd, &s, sizeof(s)) != sizeof(s)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strs = (char *)malloc(s.sh_size);
|
||||
lseek(fd, s.sh_offset, SEEK_SET);
|
||||
if (read(fd, strs, s.sh_size) != s.sh_size) {
|
||||
close(fd);
|
||||
free(strs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < e.e_shnum; i++) {
|
||||
lseek(fd, e.e_shoff + (i * e.e_shentsize), SEEK_SET);
|
||||
if (read(fd, &s, sizeof(s)) != sizeof(s)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(strs + s.sh_name, name)) {
|
||||
*_start = s.sh_offset;
|
||||
*_end = s.sh_offset + s.sh_size;
|
||||
close(fd);
|
||||
free(strs);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
free(strs);
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,86 +0,0 @@
|
|||
#define USE_GENERIC_GET_SELF_PATH
|
||||
|
||||
#if defined(__linux__)
|
||||
# include <errno.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
char buf[256], *s = buf;
|
||||
ssize_t len, blen = sizeof(buf);
|
||||
|
||||
while (1) {
|
||||
len = readlink("/proc/self/exe", s, blen-1);
|
||||
if (len == (blen-1)) {
|
||||
if (s != buf) free(s);
|
||||
blen *= 2;
|
||||
s = malloc(blen);
|
||||
} else if (len < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
buf[len] = 0;
|
||||
return strdup(buf);
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
# include <sys/sysctl.h>
|
||||
# include <errno.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
int mib[4];
|
||||
char *s;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
#if defined(__NetBSD__)
|
||||
mib[1] = KERN_PROC_ARGS;
|
||||
mib[2] = getpid();
|
||||
mib[3] = KERN_PROC_PATHNAME;
|
||||
#else
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PATHNAME;
|
||||
mib[3] = -1;
|
||||
#endif
|
||||
|
||||
r = sysctl(mib, 4, NULL, &len, NULL, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
s = malloc(len);
|
||||
r = sysctl(mib, 4, s, &len, NULL, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
# include <mach-o/dyld.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
char buf[1024], *s;
|
||||
uint32_t size = sizeof(buf);
|
||||
int r;
|
||||
|
||||
r = _NSGetExecutablePath(buf, &size);
|
||||
if (!r)
|
||||
return strdup(buf);
|
||||
else {
|
||||
s = malloc(size);
|
||||
r = _NSGetExecutablePath(s, &size);
|
||||
if (!r)
|
||||
return s;
|
||||
fprintf(stderr, "failed to get self\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
|
@ -95,6 +95,10 @@ char * volatile _configdir = "coNFIg dIRECTORy:" /* <- this tag stays, so we can
|
|||
"****************************************************************";
|
||||
static int _configdir_offset = 17; /* Skip permanent tag */
|
||||
|
||||
#define XFORM_SKIP_PROC /* empty */
|
||||
#define USE_EXE_LOOKUP_VIA_PATH
|
||||
#include "self_exe.inc"
|
||||
|
||||
typedef struct {
|
||||
char *flag;
|
||||
int arg_count;
|
||||
|
@ -174,68 +178,12 @@ static char *string_append(char *s1, char *s2)
|
|||
return s;
|
||||
}
|
||||
|
||||
static char *copy_string(char *s1)
|
||||
{
|
||||
int l1;
|
||||
char *s;
|
||||
|
||||
if (!s1) return NULL;
|
||||
|
||||
l1 = strlen(s1);
|
||||
|
||||
s = (char *)malloc(l1 + 1);
|
||||
|
||||
memcpy(s, s1, l1 + 1);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static char *do_path_append(char *s1, int l1, char *s2)
|
||||
{
|
||||
int l2;
|
||||
char *s;
|
||||
|
||||
l2 = strlen(s2);
|
||||
|
||||
s = (char *)malloc(l1 + l2 + 2);
|
||||
|
||||
memcpy(s, s1, l1);
|
||||
if (s[l1 - 1] != '/') {
|
||||
s[l1++] = '/';
|
||||
}
|
||||
|
||||
memcpy(s + l1, s2, l2);
|
||||
s[l1 + l2] = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static char *path_append(char *s1, char *s2)
|
||||
{
|
||||
return do_path_append(s1, strlen(s1), s2);
|
||||
}
|
||||
|
||||
static int executable_exists(char *path)
|
||||
{
|
||||
return (access(path, X_OK) == 0);
|
||||
}
|
||||
|
||||
static int as_int(char *_c)
|
||||
{
|
||||
unsigned char *c = (unsigned char *)_c;
|
||||
return c[0] | ((int)c[1] << 8) | ((int)c[2] << 16) | ((int)c[3] << 24);
|
||||
}
|
||||
|
||||
static int has_slash(char *s)
|
||||
{
|
||||
while (*s) {
|
||||
if (s[0] == '/')
|
||||
return 1;
|
||||
s++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *absolutize(char *p, char *d)
|
||||
{
|
||||
int l1;
|
||||
|
@ -262,107 +210,30 @@ static char *next_string(char *s)
|
|||
return s + strlen(s) + 1;
|
||||
}
|
||||
|
||||
#include "unix_self.inc"
|
||||
static int try_section_shift(const char *me, int *_start, int *_decl_end, int *_prog_end, int *_end)
|
||||
{
|
||||
int start = 0, end = 0;
|
||||
int is_prog;
|
||||
|
||||
#ifdef USE_GENERIC_GET_SELF_PATH
|
||||
static char *adjust_self_reference(char *me)
|
||||
{
|
||||
return me;
|
||||
}
|
||||
#ifdef OS_X
|
||||
{
|
||||
long len = 0;
|
||||
start = find_mach_o_segment("__PLTSCHEME", &len);
|
||||
end = start + len;
|
||||
is_prog = 1;
|
||||
}
|
||||
#else
|
||||
static char *adjust_self_reference(char *me)
|
||||
{
|
||||
return get_self_path(me);
|
||||
}
|
||||
is_prog = find_elf_section_offset(me, ".rackprog", &start, &end);
|
||||
#endif
|
||||
|
||||
typedef unsigned short ELF__Half;
|
||||
typedef unsigned int ELF__Word;
|
||||
typedef unsigned long ELF__Xword;
|
||||
typedef unsigned long ELF__Addr;
|
||||
typedef unsigned long ELF__Off;
|
||||
|
||||
typedef struct {
|
||||
unsigned char e_ident[16];
|
||||
ELF__Half e_type;
|
||||
ELF__Half e_machine;
|
||||
ELF__Word e_version;
|
||||
ELF__Addr e_entry;
|
||||
ELF__Off e_phoff;
|
||||
ELF__Off e_shoff;
|
||||
ELF__Word e_flags;
|
||||
ELF__Half e_ehsize;
|
||||
ELF__Half e_phentsize;
|
||||
ELF__Half e_phnum;
|
||||
ELF__Half e_shentsize;
|
||||
ELF__Half e_shnum;
|
||||
ELF__Half e_shstrndx;
|
||||
} ELF__Header;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ELF__Word sh_name;
|
||||
ELF__Word sh_type;
|
||||
ELF__Xword sh_flags;
|
||||
ELF__Addr sh_addr;
|
||||
ELF__Off sh_offset;
|
||||
ELF__Xword sh_size;
|
||||
ELF__Word sh_link;
|
||||
ELF__Word sh_info;
|
||||
ELF__Xword sh_addralign;
|
||||
ELF__Xword sh_entsize;
|
||||
} Elf__Shdr;
|
||||
|
||||
static int try_elf_section(const char *me, int *_start, int *_decl_end, int *_prog_end, int *_end)
|
||||
{
|
||||
int fd, i;
|
||||
ELF__Header e;
|
||||
Elf__Shdr s;
|
||||
char *strs;
|
||||
|
||||
fd = open(me, O_RDONLY, 0);
|
||||
if (fd == -1) return 0;
|
||||
|
||||
if (read(fd, &e, sizeof(e)) == sizeof(e)) {
|
||||
if ((e.e_ident[0] == 0x7F)
|
||||
&& (e.e_ident[1] == 'E')
|
||||
&& (e.e_ident[2] == 'L')
|
||||
&& (e.e_ident[3] == 'F')) {
|
||||
|
||||
lseek(fd, e.e_shoff + (e.e_shstrndx * e.e_shentsize), SEEK_SET);
|
||||
if (read(fd, &s, sizeof(s)) != sizeof(s)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strs = (char *)malloc(s.sh_size);
|
||||
lseek(fd, s.sh_offset, SEEK_SET);
|
||||
if (read(fd, strs, s.sh_size) != s.sh_size) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < e.e_shnum; i++) {
|
||||
lseek(fd, e.e_shoff + (i * e.e_shentsize), SEEK_SET);
|
||||
if (read(fd, &s, sizeof(s)) != sizeof(s)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(strs + s.sh_name, ".rackcmdl")
|
||||
|| !strcmp(strs + s.sh_name, ".rackprog")) {
|
||||
*_decl_end = (*_decl_end - *_start) + s.sh_offset;
|
||||
*_prog_end = (*_prog_end - *_start) + s.sh_offset;
|
||||
*_start = s.sh_offset;
|
||||
*_end = s.sh_offset + s.sh_size;
|
||||
close(fd);
|
||||
return !strcmp(strs + s.sh_name, ".rackprog");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (start != 0) {
|
||||
*_decl_end = (*_decl_end - *_start) + start;
|
||||
*_prog_end = (*_prog_end - *_start) + start;
|
||||
*_start = start;
|
||||
*_end = end;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
return is_prog;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -379,52 +250,7 @@ int main(int argc, char **argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (me[0] == '/') {
|
||||
/* Absolute path */
|
||||
} else if (has_slash(me)) {
|
||||
/* Relative path with a directory: */
|
||||
char *buf;
|
||||
long buflen = 4096;
|
||||
buf = (char *)malloc(buflen);
|
||||
me = path_append(getcwd(buf, buflen), me);
|
||||
free(buf);
|
||||
} else {
|
||||
/* We have to find the executable by searching PATH: */
|
||||
char *path = copy_string(getenv("PATH")), *p, *m;
|
||||
int more;
|
||||
|
||||
if (!path) {
|
||||
path = "";
|
||||
}
|
||||
|
||||
while (1) {
|
||||
/* Try each element of path: */
|
||||
for (p = path; *p && (*p != ':'); p++) { }
|
||||
if (*p) {
|
||||
*p = 0;
|
||||
more = 1;
|
||||
} else
|
||||
more = 0;
|
||||
|
||||
if (!*path)
|
||||
break;
|
||||
|
||||
m = path_append(path, me);
|
||||
|
||||
if (executable_exists(m)) {
|
||||
if (m[0] != '/')
|
||||
m = path_append(getcwd(NULL, 0), m);
|
||||
me = m;
|
||||
break;
|
||||
}
|
||||
free(m);
|
||||
|
||||
if (more)
|
||||
path = p + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
me = lookup_exe_via_path(me);
|
||||
|
||||
/* me is now an absolute path to the binary */
|
||||
|
||||
|
@ -451,7 +277,7 @@ int main(int argc, char **argv)
|
|||
/* use `me` for `-k`, unless we have a way to more directly get the
|
||||
executable file that contains embedded code; if we do, then
|
||||
argv[0] doesn't have to match the executable */
|
||||
embedding_me = adjust_self_reference(me);
|
||||
embedding_me = get_self_path(me);
|
||||
|
||||
start = as_int(config + 8);
|
||||
decl_end = as_int(config + 12);
|
||||
|
@ -460,7 +286,7 @@ int main(int argc, char **argv)
|
|||
count = as_int(config + 24);
|
||||
x11 = as_int(config + 28);
|
||||
|
||||
fix_argv = try_elf_section(embedding_me, &start, &decl_end, &prog_end, &end);
|
||||
try_section_shift(embedding_me, &start, &decl_end, &prog_end, &end);
|
||||
|
||||
{
|
||||
int offset, len;
|
||||
|
@ -566,13 +392,11 @@ int main(int argc, char **argv)
|
|||
new_argv[argpos++] = "-G";
|
||||
new_argv[argpos++] = absolutize(_configdir + _configdir_offset, me);
|
||||
|
||||
if (fix_argv) {
|
||||
/* next four args are "-k" and numbers; leave room to insert the
|
||||
filename in place of "-k", and fix the numbers to match start,
|
||||
decl_end, and prog_end */
|
||||
new_argv[argpos++] = "-Y";
|
||||
fix_argv = argpos;
|
||||
}
|
||||
/* next four args are "-k" and numbers; leave room to insert the
|
||||
filename in place of "-k", and fix the numbers to match start,
|
||||
decl_end, and prog_end */
|
||||
new_argv[argpos++] = "-Y";
|
||||
fix_argv = argpos;
|
||||
|
||||
/* Add built-in flags: */
|
||||
while (count--) {
|
||||
|
|
3
racket/src/worksp/.gitignore
vendored
3
racket/src/worksp/.gitignore
vendored
|
@ -42,3 +42,6 @@ cstartup.exe
|
|||
/liblz4.dll
|
||||
/liblz4.lib
|
||||
/liblz4.exp
|
||||
/liblz4mt.dll
|
||||
/liblz4mt.lib
|
||||
/liblz4mt.exp
|
||||
|
|
Loading…
Reference in New Issue
Block a user