cs: on Linux record embedded boot relative to ".rackboot" section

This commit is contained in:
Matthew Flatt 2018-10-24 20:54:14 -06:00
parent 8c3956a272
commit c0f14373ab
5 changed files with 81 additions and 3 deletions

View File

@ -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

View File

@ -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"

View File

@ -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)

View File

@ -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))

View File

@ -77,6 +77,54 @@ static char *get_self_path()
}
#endif
#ifdef ELF_FIND_BOOT_SECTION
# include <elf.h>
# include <fcntl.h>
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,