From 61d4fefcb198a69e0b4e980c268ff84ecf61326f Mon Sep 17 00:00:00 2001 From: Daniel Colascione Date: Sun, 25 Feb 2018 20:38:35 -0800 Subject: [PATCH] Rationalize temacs init and dump mode selection. --- configure.ac | 102 +++++++++++++++------ lisp/loadup.el | 12 +-- lisp/startup.el | 6 +- src/Makefile.in | 8 +- src/alloc.c | 6 -- src/emacs.c | 231 ++++++++++++++++++++++++------------------------ src/gmalloc.c | 18 ++-- src/lisp.h | 15 ++++ src/pdumper.c | 2 +- src/sheap.c | 1 - src/sheap.h | 1 - src/sysdep.c | 2 +- 12 files changed, 227 insertions(+), 177 deletions(-) diff --git a/configure.ac b/configure.ac index dbc9edd4165..e8ad7f72e59 100644 --- a/configure.ac +++ b/configure.ac @@ -311,24 +311,87 @@ this option's value should be 'yes', 'no', 'alsa', 'oss', or 'bsd-ossaudio'.]) ], [with_sound=$with_features]) -OPTION_DEFAULT_ON([pdumper], [don't compile with portable dumper support]) -if test "$with_pdumper" = "yes"; then - AC_DEFINE(HAVE_PDUMPER, 1, [Define to build with portable dumper support]) -fi +AC_ARG_WITH([pdumper], + AS_HELP_STRING( + [--with-pdumper=VALUE], + [enable pdumper support unconditionally + ('yes', 'no', or 'auto': default 'auto')]), + [ case "${withval}" in + yes|no|auto) val=$withval ;; + *) AC_MSG_ERROR( + ['--with-pdumper=$withval' is invalid; +this option's value should be 'yes' or 'no'.]) ;; + esac + with_pdumper=$val + ], + [with_pdumper=auto]) + +AC_ARG_WITH([unexec], + AS_HELP_STRING( + [--with-unexec=VALUE], + [enable unexec support unconditionally + ('yes', 'no', or 'auto': default 'auto')]), + [ case "${withval}" in + yes|no|auto) val=$withval ;; + *) AC_MSG_ERROR( + ['--with-unexec=$withval' is invalid; +this option's value should be 'yes' or 'no'.]) ;; + esac + with_unexec=$val + ], + [with_unexec=auto]) AC_ARG_WITH([dumping],[AS_HELP_STRING([--with-dumping=VALUE], [kind of dumping to use for initial Emacs build -(VALUE one of: pdumper, unexec, no; default pdumper)])], +(VALUE one of: pdumper, unexec, none; default pdumper)])], [ case "${withval}" in - pdumper|unexec|no) val=$withval ;; + pdumper|unexec|none) val=$withval ;; *) AC_MSG_ERROR(['--with-dumping=$withval is invalid; -this option's value should be 'pdumper', 'unexec', or 'no'.]) +this option's value should be 'pdumper', 'unexec', or 'none'.]) ;; esac with_dumping=$val ], [with_dumping=pdumper]) +if test "$with_pdumper" = "auto"; then + if test "$with_dumping" = "pdumper"; then + with_pdumper=yes + else + with_pdumper=no + fi +fi + +if test "$with_unexec" = "auto"; then + if test "$with_dumping" = "unexec"; then + with_unexec=yes + else + with_unexec=no + fi +fi + +if test "$with_dumping" = "pdumper" && test "$with_pdumper" = "no"; then + AC_MSG_ERROR(['--with-dumping=pdumper' requires pdumper support]) +fi + +if test "$with_dumping" = "unexec" && test "$with_unexec" = "no"; then + AC_MSG_ERROR(['--with-dumping=unexec' requires unexec support]) +fi + +if test "$with_pdumper" = "yes"; then + AC_DEFINE(HAVE_PDUMPER, 1, [Define to build with portable dumper support]) +fi + +if test "$with_unexec" = "yes"; then + CANNOT_DUMP=no +else + CANNOT_DUMP=yes +fi + +DUMPING=$with_dumping +AC_SUBST(DUMPING) +AC_SUBST(CANNOT_DUMP) + dnl FIXME currently it is not the last. dnl This should be the last --with option, because --with-x is dnl added later on when we find the file name of X, and it's best to @@ -1226,31 +1289,10 @@ AC_PATH_PROG(GZIP_PROG, gzip) test $with_compress_install != yes && test -n "$GZIP_PROG" && \ GZIP_PROG=" # $GZIP_PROG # (disabled by configure --without-compress-install)" -if test -n "$CANNOT_DUMP" && test "$with_dumping" = "unexec"; then - with_dumping=no -fi - if test "$with_dumping" = "unexec" && test "$opsys" = "nacl"; then AC_MSG_ERROR([nacl is not compatible with --with-dumping=unexec]) fi -if test "$with_dumping" != "unexec"; then - CANNOT_DUMP=yes -fi - -if test -n "$CANNOT_DUMP"; then - if test "$with_dumping" = "unexec"; then - AC_MSG_ERROR([CANNOT_DUMP is incompatible with --with-dumping=unexec]) - fi - CANNOT_DUMP=yes -else - CANNOT_DUMP=no -fi - -DUMPING=$with_dumping -AC_SUBST(DUMPING) -AC_SUBST(CANNOT_DUMP) - AC_CACHE_CHECK([for 'find' args to delete a file], [emacs_cv_find_delete], [if touch conftest.tmp && find conftest.tmp -delete 2>/dev/null && @@ -1419,7 +1461,7 @@ AC_CACHE_CHECK([whether addresses are sanitized], [emacs_cv_sanitize_address=no])]) if test "$CANNOT_DUMP" = "yes"; then - AC_DEFINE(CANNOT_DUMP, 1, [Define if Emacs cannot be dumped on your system.]) + AC_DEFINE(CANNOT_DUMP, 1, [Define if Emacs should not support unexec.]) elif test "$emacs_cv_sanitize_address" = yes; then AC_MSG_WARN([[Addresses are sanitized; suggest CANNOT_DUMP=yes]]) fi @@ -5511,6 +5553,8 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D Does Emacs use toolkit scroll bars? ${USE_TOOLKIT_SCROLL_BARS} Does Emacs support Xwidgets (requires gtk3)? ${HAVE_XWIDGETS} Does Emacs have threading support in lisp? ${threads_enabled} + Does Emacs support the portable dumper? ${with_pdumper} + Does Emacs support legacy unexec dumping? ${with_unexec} Which dumping strategy does Emacs use? ${with_dumping} "]) diff --git a/lisp/loadup.el b/lisp/loadup.el index e166755e036..2189c46abf5 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -26,8 +26,8 @@ ;; This is loaded into a bare Emacs to make a dumpable one. -;; Emacs injects the variable `dump-mode' to tell us how to dump. We unintern -;; it before allowing user code to run. +;; Emacs injects the variable `dump-mode' to tell us how to dump. +;; We unintern it before allowing user code to run. ;; If you add a file to be loaded here, keep the following points in mind: @@ -381,9 +381,9 @@ lost after dumping"))) ;; Determine which build number to use ;; based on the executables that now exist. (if (and (or - (and (equal (last command-line-args) '("dump")) + (and (equal dump-mode "dump") (fboundp 'dump-emacs)) - (and (equal (last command-line-args) '("pdump")) + (and (equal dump-mode "pdump") (fboundp 'dump-emacs-portable))) (not (eq system-type 'ms-dos))) (let* ((base (concat "emacs-" emacs-version ".")) @@ -403,9 +403,9 @@ lost after dumping"))) (message "Finding pointers to doc strings...") (if (and (or (and (fboundp 'dump-emacs) - (equal (last command-line-args) '("dump"))) + (equal dump-mode "dump")) (and (fboundp 'dump-emacs-portable) - (equal (last command-line-args) '("pdump"))))) + (equal dump-mode "pdump")))) (Snarf-documentation "DOC") (condition-case nil (Snarf-documentation "DOC") diff --git a/lisp/startup.el b/lisp/startup.el index 4105c1db2d6..33ab85050f3 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1048,7 +1048,8 @@ please check its value") (let* ((longopts '(("--no-init-file") ("--no-site-file") ("--no-x-resources") ("--debug-init") ("--user") ("--iconic") ("--icon-type") ("--quick") - ("--no-blinking-cursor") ("--basic-display"))) + ("--no-blinking-cursor") ("--basic-display") + ("--dump-file") ("--temacs"))) (argi (pop args)) (orig-argi argi) argval) @@ -1100,6 +1101,9 @@ please check its value") (push '(visibility . icon) initial-frame-alist)) ((member argi '("-nbc" "-no-blinking-cursor")) (setq no-blinking-cursor t)) + ((member argi '("-dump-file" "-temacs")) ; Handled in C + (or argval (pop args)) + (setq argval nil)) ;; Push the popped arg back on the list of arguments. (t (push argi args) diff --git a/src/Makefile.in b/src/Makefile.in index 1e9e97ab170..ab9bc5b89c8 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -553,9 +553,9 @@ emacs$(EXEEXT): temacs$(EXEEXT) \ $(lispsource)/international/charprop.el ${charsets} ifeq ($(DUMPING),pdumper) cp -f temacs$(EXEEXT) $@ - LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup pdump + LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup --temacs=pdump else ifeq ($(DUMPING),unexec) - LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup dump + LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup --temacs=dump ifneq ($(PAXCTL_dumped),) $(PAXCTL_dumped) $@ endif @@ -779,9 +779,9 @@ bootstrap-emacs$(EXEEXT) $(bootstrap_pdmp): temacs$(EXEEXT) ifeq ($(DUMPING),pdumper) rm -f $(bootstrap_pdmp) cp -f temacs$(EXEEXT) bootstrap-emacs$(EXEEXT) - $(RUN_TEMACS) --batch $(BUILD_DETAILS) --load loadup pbootstrap + $(RUN_TEMACS) --batch $(BUILD_DETAILS) -l loadup --temacs=pbootstrap else ifeq ($(DUMPING),unexec) - $(RUN_TEMACS) --batch $(BUILD_DETAILS) --load loadup bootstrap + $(RUN_TEMACS) --batch $(BUILD_DETAILS) -l loadup --temacs=bootstrap ifneq ($(PAXCTL_dumped),) $(PAXCTL_dumped) emacs$(EXEEXT) endif diff --git a/src/alloc.c b/src/alloc.c index 6f81195cc3c..da9526e518c 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -190,9 +190,6 @@ alloc_unexec_pre (void) if (!malloc_state_ptr) fatal ("malloc_get_state: %s", strerror (errno)); # endif -# ifdef HYBRID_MALLOC - bss_sbrk_did_unexec = true; -# endif } void @@ -201,9 +198,6 @@ alloc_unexec_post (void) # ifdef DOUG_LEA_MALLOC free (malloc_state_ptr); # endif -# ifdef HYBRID_MALLOC - bss_sbrk_did_unexec = false; -# endif } #endif diff --git a/src/emacs.c b/src/emacs.c index 7ed4f2758e2..b8ebe9ef220 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -642,74 +642,63 @@ argmatch (char **argv, int argc, const char *sstr, const char *lstr, } } -/* Close standard output and standard error, reporting any write - errors as best we can. This is intended for use with atexit. */ -static void -close_output_streams (void) -{ - if (close_stream (stdout) != 0) - { - emacs_perror ("Write error to standard output"); - _exit (EXIT_FAILURE); - } - - /* Do not close stderr if addresses are being sanitized, as the - sanitizer might report to stderr after this function is - invoked. */ - if (!ADDRESS_SANITIZER && close_stream (stderr) != 0) - _exit (EXIT_FAILURE); -} - -ATTRIBUTE_UNUSED static bool string_starts_with_p (const char* string, const char* prefix) { return strncmp (string, prefix, strlen (prefix)) == 0; } -#ifdef HAVE_PDUMPER - -#define DUMP_FILE_ARGUMENT "--dump-file" - +/* Return the value of GNU-style long argument ARGUMENT if given on + command line. ARGUMENT must begin with "-". If ARGUMENT is not + given, return NULL. */ static char * -find_and_remove_dump_file_argument (int *inout_argc, char ***inout_argv) +find_argument (const char *argument, int argc, char **argv) { - int argc = *inout_argc; - char **argv = *inout_argv; char *found = NULL; int i; + eassert (argument[0] == '-'); + for (i = 1; i < argc; ++i) - if (string_starts_with_p (argv[i], DUMP_FILE_ARGUMENT) && - ((argv[i] + strlen (DUMP_FILE_ARGUMENT))[0] == '=' || - (argv[i] + strlen (DUMP_FILE_ARGUMENT))[0] == '\0')) + if (string_starts_with_p (argv[i], argument) && + ((argv[i] + strlen (argument))[0] == '=' || + (argv[i] + strlen (argument))[0] == '\0')) { int j = i; - found = argv[j++] + strlen (DUMP_FILE_ARGUMENT); + found = argv[j++] + strlen (argument); if (*found == '=') ++found; else if (i < argc) found = argv[j++]; else - { - fprintf (stderr, "%s: no argument given for %s\n", - argv[0], DUMP_FILE_ARGUMENT); - exit (1); - } - - memmove (&argv[i], &argv[j], sizeof (*argv) * (argc - j)); - argc -= (j - i); - argv[argc] = NULL; + fatal ("no argument given for %s", argument); break; } else if (strcmp (argv[i], "--") == 0) break; - - *inout_argc = argc; - *inout_argv = argv; return found; } +/* Close standard output and standard error, reporting any write + errors as best we can. This is intended for use with atexit. */ +static void +close_output_streams (void) +{ + if (close_stream (stdout) != 0) + { + emacs_perror ("Write error to standard output"); + _exit (EXIT_FAILURE); + } + + /* Do not close stderr if addresses are being sanitized, as the + sanitizer might report to stderr after this function is + invoked. */ + if (!ADDRESS_SANITIZER && close_stream (stderr) != 0) + _exit (EXIT_FAILURE); +} + +#ifdef HAVE_PDUMPER + static const char * dump_error_to_string (enum pdumper_load_result result) { @@ -732,33 +721,27 @@ dump_error_to_string (enum pdumper_load_result result) } } +#define PDUMP_FILE_ARG "--dump-file" + static enum pdumper_load_result -load_dump (int *inout_argc, - char ***inout_argv, - const char *argv0_base, - const char** out_dump_file) +load_pdump (int argc, char **argv, const char** out_dump_file) { - int argc = *inout_argc; - char **argv = *inout_argv; - const char *suffix = ".pdmp"; + const char *const suffix = ".pdmp"; + const char *const argv0_base = "emacs"; enum pdumper_load_result result; #ifdef WINDOWSNT size_t argv0_len; #endif - /* Look for an explicitly-specified dump file. */ + /* TODO: maybe more thoroughly scrub process environment in order to + make this use case possible? Right now, we assume that things we + don't touch are zero-initialized, and in an unexeced Emacs, this + assumption doesn't hold. */ + eassert (!initialized); + /* Look for an explicitly-specified dump file. */ const char *path_exec = PATH_EXEC; - char *dump_file = find_and_remove_dump_file_argument (&argc, &argv); - if (initialized && dump_file) - /* TODO: maybe more thoroughly scrub process environment in order - to make this use case possible? Right now, we assume that - things we don't touch are zero-initialized, and in an unexeced - Emacs, this assumption doesn't hold. */ - fatal ("cannot load dump file into unexeced Emacs"); - - if (initialized) - abort (); + char *dump_file = find_argument (PDUMP_FILE_ARG, argc, argv); result = PDUMPER_NOT_LOADED; if (dump_file) @@ -797,7 +780,6 @@ load_dump (int *inout_argc, if the user copies and renames it. FIXME: this doesn't work with emacs-XX.YY.ZZ.pdmp versioned files. */ - argv0_base = "emacs"; #ifdef WINDOWSNT /* On MS-Windows, PATH_EXEC normally starts with a literal "%emacs_dir%", so it will never work without some tweaking. */ @@ -816,8 +798,6 @@ load_dump (int *inout_argc, out: *out_dump_file = dump_file ? strdup (dump_file) : NULL; - *inout_argc = argc; - *inout_argv = argv; return result; } #endif /* HAVE_PDUMPER */ @@ -846,25 +826,64 @@ main (int argc, char **argv) /* Record (approximately) where the stack begins. */ stack_bottom = (char *) &stack_bottom_variable; - /* Figure out where we are. Fancy filesystem functions aren't - available at this point, so use pure text manipulation. */ - const char *argv0_base = strrchr (argv[0], DIRECTORY_SEP); -#ifdef WINDOWSNT - /* Consider backslashes and the .exe extension. */ - const char *argv0_alt = strrchr (argv[0], '\\'); - - if (argv0_alt > argv0_base) - argv0_base = argv0_alt; - argv0_base = argv0_base ? argv0_base + 1 : argv[0]; - bool is_temacs = - c_strncasecmp ("temacs", argv0_base, 6) == 0 - && strlen (argv0_base) >= 4 - && c_strcasecmp (argv0_base + strlen (argv0_base) - 4, ".exe") == 0; -#else - argv0_base = argv0_base ? argv0_base + 1 : argv[0]; - bool is_temacs = strcmp ("temacs", argv0_base) == 0; -#endif + const char *dump_mode = NULL; const char *loaded_dump = NULL; + const char *temacs = find_argument ("--temacs", argc, argv); +#ifdef HAVE_PDUMPER + bool attempt_load_pdump = false; +#endif + + /* Look for this argument first, before any heap allocation, so we + can set heap flags properly if we're going to unexec. */ + if (!initialized && temacs) + { +#ifndef CANNOT_DUMP + if (strcmp (temacs, "dump") == 0 || + strcmp (temacs, "bootstrap") == 0) + gflags.will_dump_with_unexec_ = true; +#endif +#ifdef HAVE_PDUMPER + if (strcmp (temacs, "pdump") == 0 || + strcmp (temacs, "pbootstrap") == 0) + gflags.will_dump_with_pdumper_ = true; +#endif +#if defined (HAVE_PDUMPER) || !defined (CANNOT_DUMP) + if (strcmp (temacs, "bootstrap") == 0 || + strcmp (temacs, "pbootstrap") == 0) + gflags.will_bootstrap_ = true; + gflags.will_dump_ = + will_dump_with_pdumper_p () || + will_dump_with_unexec_p (); + if (will_dump_p ()) + dump_mode = temacs; +#endif + if (!dump_mode) + fatal ("Invalid temacs mode '%s'", temacs); + } + else if (temacs) + { + fatal ("--temacs not supported for unexeced emacs"); + } + else if (initialized) + { +#ifdef HAVE_PDUMPER + if (find_argument (PDUMP_FILE_ARG, argc, argv)) + fatal ("%s not supported in unexeced emacs", PDUMP_FILE_ARG); +#endif + } + else + { + eassert (!initialized); + eassert (!temacs); +#ifdef PDUMP_FILE_ARG + attempt_load_pdump = true; +#endif + } + +#ifndef CANNOT_DUMP + if (!will_dump_with_unexec_p ()) + gflags.will_not_unexec_ = true; +#endif #if defined WINDOWSNT || defined HAVE_NTGUI /* Set global variables used to detect Windows version. Do this as @@ -883,48 +902,24 @@ main (int argc, char **argv) w32_init_main_thread (); #endif - const char *dump_mode = NULL; - if (!initialized && is_temacs) - { -#ifndef CANNOT_DUMP - if (strcmp (argv[argc - 1], "dump") == 0 || - strcmp (argv[argc - 1], "bootstrap") == 0) - gflags.will_dump_with_unexec_ = true; -#endif #ifdef HAVE_PDUMPER - if (strcmp (argv[argc - 1], "pdump") == 0 || - strcmp (argv[argc - 1], "pbootstrap") == 0) - gflags.will_dump_with_pdumper_ = true; -#endif -#if defined (HAVE_PDUMPER) || !defined (CANNOT_DUMP) - if (strcmp (argv[argc - 1], "bootstrap") == 0 || - strcmp (argv[argc - 1], "pbootstrap") == 0) - gflags.will_bootstrap_ = true; - gflags.will_dump_ = - will_dump_with_pdumper_p () || - will_dump_with_unexec_p (); - if (will_dump_p ()) - dump_mode = argv[argc - 1]; -#endif - } - else if (!is_temacs) + if (attempt_load_pdump) { -#ifdef HAVE_PDUMPER struct timeval start; gettimeofday (&start, NULL); - const char *loaded_dump = NULL; - enum pdumper_load_result result = - load_dump (&argc, &argv, argv0_base, &loaded_dump); + enum pdumper_load_result result = load_pdump (argc, argv, &loaded_dump); struct timeval end; gettimeofday (&end, NULL); double tdif = - 1000.0 * (end.tv_sec - start.tv_sec) - + (end.tv_usec - start.tv_usec) / 1.0e3; - fprintf (stderr, "load_dump %s %g milliseconds: result=%d\n", - loaded_dump ? "completed in" : "failed after", - tdif, (int) result); -#endif + 1000.0 * (end.tv_sec - start.tv_sec) + + (end.tv_usec - start.tv_usec) / 1.0e3; + fprintf (stderr, "load_dump %s %g milliseconds%s%s\n", + loaded_dump ? "completed in" : "failed after", + tdif, + loaded_dump ? "" : ": ", + dump_error_to_string (result)); } +#endif /* True if address randomization interferes with memory allocation. */ # ifdef __PPC64__ @@ -1923,7 +1918,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem if (dump_mode) Vdump_mode = build_string (dump_mode); if (loaded_dump) - Vdump_file_name = build_string (loaded_dump); // XXX: filesystem decode + Vdump_file_name = build_string (loaded_dump); // XXX: decode /* Enter editor command loop. This never returns. */ Frecursive_edit (); @@ -2372,6 +2367,9 @@ You must run Emacs in batch mode in order to dump it. */) if (dumped_with_unexec_p ()) error ("Emacs can be dumped using unexec only once"); + if (definitely_will_not_unexec_p ()) + error ("This Emacs instance was not started in temacs mode"); + #if defined GNU_LINUX && !defined CANNOT_DUMP /* Warn if the gap between BSS end and heap start is larger than this. */ @@ -2791,7 +2789,6 @@ Don't rely on it for testing whether a feature you want to use is available. */ DEFVAR_BOOL ("noninteractive", noninteractive1, doc: /* Non-nil means Emacs is running without interactive terminal. */); - DEFVAR_LISP ("dump-file-name", Vdump_file_name, doc: /* Name of the dump file used to start this Emacs process. */); diff --git a/src/gmalloc.c b/src/gmalloc.c index ebba789f610..977c841180f 100644 --- a/src/gmalloc.c +++ b/src/gmalloc.c @@ -36,10 +36,7 @@ License along with this library. If not, see . #include #endif -#ifdef emacs -# include "lisp.h" -#endif - +#include "lisp.h" #include "ptr-bounds.h" #ifdef HAVE_MALLOC_H @@ -78,7 +75,6 @@ extern void *(*__morecore) (ptrdiff_t); #ifdef HYBRID_MALLOC # include "sheap.h" -# define DUMPED bss_sbrk_did_unexec #endif #ifdef __cplusplus @@ -1510,7 +1506,7 @@ static void * gdefault_morecore (ptrdiff_t increment) { #ifdef HYBRID_MALLOC - if (!DUMPED) + if (!definitely_will_not_unexec_p ()) { return bss_sbrk (increment); } @@ -1728,6 +1724,8 @@ extern int posix_memalign (void **memptr, size_t alignment, size_t size); static bool allocated_via_gmalloc (void *ptr) { + if (!__malloc_initialized) + return false; size_t block = BLOCK (ptr); size_t blockmax = _heaplimit - 1; return block <= blockmax && _heapinfo[block].busy.type != 0; @@ -1739,7 +1737,7 @@ allocated_via_gmalloc (void *ptr) void * hybrid_malloc (size_t size) { - if (DUMPED) + if (definitely_will_not_unexec_p ()) return malloc (size); return gmalloc (size); } @@ -1747,7 +1745,7 @@ hybrid_malloc (size_t size) void * hybrid_calloc (size_t nmemb, size_t size) { - if (DUMPED) + if (definitely_will_not_unexec_p ()) return calloc (nmemb, size); return gcalloc (nmemb, size); } @@ -1765,7 +1763,7 @@ hybrid_free (void *ptr) void * hybrid_aligned_alloc (size_t alignment, size_t size) { - if (!DUMPED) + if (!definitely_will_not_unexec_p ()) return galigned_alloc (alignment, size); /* The following is copied from alloc.c */ #ifdef HAVE_ALIGNED_ALLOC @@ -1788,7 +1786,7 @@ hybrid_realloc (void *ptr, size_t size) return hybrid_malloc (size); if (!allocated_via_gmalloc (ptr)) return realloc (ptr, size); - if (!DUMPED) + if (!definitely_will_not_unexec_p ()) return grealloc (ptr, size); /* The dumped emacs is trying to realloc storage allocated before diff --git a/src/lisp.h b/src/lisp.h index 45e8a0d7912..98eb87dbcef 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -647,6 +647,8 @@ extern struct gflags { /* Set in an Emacs process that has been restored from an unexec dump. */ bool dumped_with_unexec_ : 1; + /* We promise not to unexec: useful for hybrid malloc. */ + bool will_not_unexec_ : 1; #endif } gflags; @@ -710,6 +712,19 @@ dumped_with_unexec_p (void) #endif } +/* This function is the opposite of will_dump_with_unexec_p(), except + that it returns false before main runs. It's important to use + gmalloc for any pre-main allocations if we're going to unexec. */ +INLINE bool +definitely_will_not_unexec_p (void) +{ +#ifdef CANNOT_DUMP + return true; +#else + return gflags.will_not_unexec_; +#endif +} + /* Defined in floatfns.c. */ extern double extract_float (Lisp_Object); diff --git a/src/pdumper.c b/src/pdumper.c index a9efaf3b6d5..83141db4ed6 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -3572,7 +3572,7 @@ dump_check_dump_off (struct dump_context *ctx, dump_off dump_offset) static void dump_check_emacs_off (dump_off emacs_off) { - eassert (labs (emacs_off) <= 30*1024*1024); + eassert (labs (emacs_off) <= 60*1024*1024); } static void diff --git a/src/sheap.c b/src/sheap.c index 882cb021e23..b1ae0e0ae94 100644 --- a/src/sheap.c +++ b/src/sheap.c @@ -31,7 +31,6 @@ static int debug_sheap; char bss_sbrk_buffer[STATIC_HEAP_SIZE]; char *max_bss_sbrk_ptr; -bool bss_sbrk_did_unexec; void * bss_sbrk (ptrdiff_t request_size) diff --git a/src/sheap.h b/src/sheap.h index e17fd523df3..e7cb0d03129 100644 --- a/src/sheap.h +++ b/src/sheap.h @@ -27,5 +27,4 @@ enum { STATIC_HEAP_SIZE = sizeof (Lisp_Object) << 22 }; extern char bss_sbrk_buffer[STATIC_HEAP_SIZE]; extern char *max_bss_sbrk_ptr; -extern bool bss_sbrk_did_unexec; extern void *bss_sbrk (ptrdiff_t); diff --git a/src/sysdep.c b/src/sysdep.c index 17e113ee9e6..c374ac773ba 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -250,7 +250,7 @@ get_current_dir_name_or_unreachable (void) # if HAVE_GET_CURRENT_DIR_NAME && !BROKEN_GET_CURRENT_DIR_NAME # ifdef HYBRID_MALLOC - bool use_libc = bss_sbrk_did_unexec; + bool use_libc = will_dump_with_unexec_p (); # else bool use_libc = true; # endif -- 2.39.5