From c0f14373abe3e5874bdb5e86bfeed8b5f76ae863 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 24 Oct 2018 20:54:14 -0600 Subject: [PATCH] cs: on Linux record embedded boot relative to ".rackboot" section --- racket/src/cs/c/Makefile.in | 4 +-- racket/src/cs/c/configure | 5 +++ racket/src/cs/c/configure.ac | 4 +++ racket/src/cs/c/embed-boot.rkt | 13 +++++++- racket/src/cs/c/main.c | 58 ++++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 3 deletions(-) diff --git a/racket/src/cs/c/Makefile.in b/racket/src/cs/c/Makefile.in index 824be3d825..c6ade334bd 100644 --- a/racket/src/cs/c/Makefile.in +++ b/racket/src/cs/c/Makefile.in @@ -131,10 +131,10 @@ racket.boot: racket.so EMBED_DEPS = $(srcdir)/embed-boot.rkt racketcs@NOT_OSX@: raw_racketcs racket.boot $(EMBED_DEPS) - $(BOOTSTRAP_RACKET) $(srcdir)/embed-boot.rkt @COMPRESS_COMP@ raw_racketcs racketcs $(SCHEME_INC) racket.boot + $(BOOTSTRAP_RACKET) $(srcdir)/embed-boot.rkt @ELF_COMP@ @COMPRESS_COMP@ raw_racketcs racketcs $(SCHEME_INC) racket.boot gracketcs@NOT_OSX@: raw_gracketcs racket.boot $(EMBED_DEPS) - $(BOOTSTRAP_RACKET) $(srcdir)/embed-boot.rkt @COMPRESS_COMP@ raw_gracketcs gracketcs $(SCHEME_INC) racket.boot + $(BOOTSTRAP_RACKET) $(srcdir)/embed-boot.rkt @ELF_COMP@ @COMPRESS_COMP@ raw_gracketcs gracketcs $(SCHEME_INC) racket.boot BOOT_OBJS = boot.o $(SCHEME_INC)/kernel.o rktio/librktio.a diff --git a/racket/src/cs/c/configure b/racket/src/cs/c/configure index 7a02a8c69c..ffc630b04c 100755 --- a/racket/src/cs/c/configure +++ b/racket/src/cs/c/configure @@ -629,6 +629,7 @@ FRAMEWORK_INSTALL_DIR SCHEME_CONFIG_ARGS MAKE_BUILD_SCHEME SCHEME_SRC +ELF_COMP COMPRESS_COMP CONFIGURE_RACKET_SO_COMPILE NOT_OSX @@ -2734,6 +2735,7 @@ OSX="not_osx" NOT_OSX="" CONFIGURE_RACKET_SO_COMPILE="" COMPRESS_COMP="" +ELF_COMP="" FRAMEWORK_INSTALL_DIR='$(libpltdir)' FRAMEWORK_PREFIX='@executable_path/../lib/' @@ -3661,6 +3663,8 @@ case "$host_os" in linux*) MACH_OS=le LIBS="${LIBS} -lrt" + CPPFLAGS="${CPPFLAGS} -DELF_FIND_BOOT_SECTION" + ELF_COMP="--expect-elf" ;; osf1*) ;; @@ -4453,6 +4457,7 @@ CPPFLAGS="$CPPFLAGS $PREFLAGS" + makefiles="Makefile" diff --git a/racket/src/cs/c/configure.ac b/racket/src/cs/c/configure.ac index 5eb51cbd81..c199fd234a 100644 --- a/racket/src/cs/c/configure.ac +++ b/racket/src/cs/c/configure.ac @@ -102,6 +102,7 @@ OSX="not_osx" NOT_OSX="" CONFIGURE_RACKET_SO_COMPILE="" COMPRESS_COMP="" +ELF_COMP="" FRAMEWORK_INSTALL_DIR='$(libpltdir)' FRAMEWORK_PREFIX='@executable_path/../lib/' @@ -152,6 +153,8 @@ case "$host_os" in linux*) MACH_OS=le LIBS="${LIBS} -lrt" + CPPFLAGS="${CPPFLAGS} -DELF_FIND_BOOT_SECTION" + ELF_COMP="--expect-elf" ;; osf1*) ;; @@ -423,6 +426,7 @@ AC_SUBST(OSX) AC_SUBST(NOT_OSX) AC_SUBST(CONFIGURE_RACKET_SO_COMPILE) AC_SUBST(COMPRESS_COMP) +AC_SUBST(ELF_COMP) AC_SUBST(SCHEME_SRC) AC_SUBST(MAKE_BUILD_SCHEME) AC_SUBST(SCHEME_CONFIG_ARGS) diff --git a/racket/src/cs/c/embed-boot.rkt b/racket/src/cs/c/embed-boot.rkt index 2524c3132c..6425813b5d 100644 --- a/racket/src/cs/c/embed-boot.rkt +++ b/racket/src/cs/c/embed-boot.rkt @@ -5,10 +5,14 @@ compiler/private/elf "adjust-compress.rkt") +(define expect-elf? #f) + (command-line #:once-each [("--compress") "Leave compiled code files as compressed" (enable-compress!)] + [("--expect-elf") "Record offset from ELF section" + (set! expect-elf? #t)] #:args (src-file dest-file boot-dir racket.boot) (define bstr1 (adjust-compress (file->bytes (build-path boot-dir "petite.boot")))) @@ -51,7 +55,12 @@ [start-pos ;; Success as ELF (ensure-executable dest-file) - start-pos] + (cond + [expect-elf? + ;; Find ".rackboot" at run time: + 0] + [else + start-pos])] [else ;; Not ELF; just append to the end (copy-file src-file dest-file #t) @@ -63,6 +72,8 @@ (lambda (o) (file-position o pos) (write-bytes data o))) + (when expect-elf? + (error 'embed-boot "expected ELF")) pos])])) (define-values (i o) (open-input-output-file dest-file #:exists 'update)) diff --git a/racket/src/cs/c/main.c b/racket/src/cs/c/main.c index 7a1ae3f135..274a23d52c 100644 --- a/racket/src/cs/c/main.c +++ b/racket/src/cs/c/main.c @@ -77,6 +77,54 @@ static char *get_self_path() } #endif + +#ifdef ELF_FIND_BOOT_SECTION +# include +# include + +static long find_boot_section(char *me) +{ + int fd, i; + Elf64_Ehdr e; + Elf64_Shdr s; + char *strs; + + fd = open(me, O_RDONLY, 0); + if (fd == -1) return 0; + + 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; +} +#endif + + #ifdef _MSC_VER static char *get_self_path() { @@ -129,6 +177,16 @@ int main(int argc, char **argv) memcpy(&pos2, boot_file_data + boot_file_offset + 4, sizeof(pos2)); memcpy(&pos3, boot_file_data + boot_file_offset + 8, sizeof(pos2)); +#ifdef ELF_FIND_BOOT_SECTION + { + long boot_offset; + boot_offset = find_boot_section(self); + pos1 += boot_offset; + pos2 += boot_offset; + pos3 += boot_offset; + } +#endif + racket_boot(argc, argv, self, segment_offset, extract_coldir(), extract_configdir(), pos1, pos2, pos3,