From 15e2b14f03796467fab8e8086d293a5813afaa5b Mon Sep 17 00:00:00 2001 From: Pip Cet Date: Tue, 20 Aug 2024 18:31:05 +0000 Subject: [PATCH] Unexec removal: Main part * configure.ac: Remove unexec-specific parts. (EMACS_CONFIG_FEATURES): Always report that we do not have the UNEXEC feature. (AC_ECHO): No longer display a line about the unexec feature. * lisp/loadup.el: * lisp/startup.el: Remove unexec-specific code. * src/Makefile.in (base_obj): Drop 'UNEXEC_OBJ'. * src/alloc.c (staticvec): Never initialize this variable. (BLOCK_ALIGN): Always allow large blocks. (mmap_lisp_allowed_p): Remove unexec-specific code. * src/buffer.c (init_buffer): * src/conf_post.h (ADDRESS_SANITIZER): * src/emacs.c (load_pdump, main): Remove unexec-specific code. (Fdump_emacs): Remove function. (syms_of_emacs): Remove 'Fdump_emacs'. * src/lastfile.c: Remove unexec-specific code. * src/lisp.h (gflags): Remove unexec-specific flags. (will_dump_p, will_bootstrap_p, will_dump_with_unexec_p) (dumped_with_unexec_p, definitely_will_not_unexec_p): Remove or adjust predicates. (SUBR_SECTION_ATTRIBUTE): Remove unexec-specific definition. * src/pdumper.c (Fdump_emacs_portable): Remove unexec-specific warning. * src/process.c (init_process_emacs): Remove !unexec condition * src/sysdep.c (maybe_disable_address_randomization): Adjust comment. (init_signals): * src/timefns.c (init_timefns): Remove unexec-specific code. * src/w32heap.c (report_temacs_memory_usage): Remove function. * src/w32heap.h: Adjust comment. * src/w32image.c (globals_of_w32image): Remove unexec-specific code. --- configure.ac | 246 +----------------------------------------------- lisp/loadup.el | 6 +- lisp/startup.el | 4 +- src/Makefile.in | 8 +- src/alloc.c | 22 +---- src/buffer.c | 41 -------- src/conf_post.h | 24 ----- src/emacs.c | 169 +-------------------------------- src/lastfile.c | 11 --- src/lisp.h | 65 +------------ src/pdumper.c | 6 -- src/process.c | 67 ++++++------- src/sysdep.c | 10 +- src/timefns.c | 29 ------ src/w32heap.c | 25 ----- src/w32heap.h | 2 +- src/w32image.c | 2 - 17 files changed, 55 insertions(+), 682 deletions(-) diff --git a/configure.ac b/configure.ac index 1c7545ef984..4808c4fa9c1 100644 --- a/configure.ac +++ b/configure.ac @@ -444,28 +444,13 @@ this option's value should be 'yes' or 'no'.]) ;; ], [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, none; default pdumper)])], +(VALUE one of: pdumper, none; default pdumper)])], [ case "${withval}" in - pdumper|unexec|none) val=$withval ;; + pdumper|none) val=$withval ;; *) AC_MSG_ERROR(['--with-dumping=$withval is invalid; -this option's value should be 'pdumper', 'unexec', or 'none'.]) +this option's value should be 'pdumper' or 'none'.]) ;; esac with_dumping=$val @@ -480,22 +465,10 @@ if test "$with_pdumper" = "auto"; then 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]) @@ -2072,10 +2045,6 @@ 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 "$with_dumping" = "unexec" && test "$opsys" = "nacl"; then - AC_MSG_ERROR([nacl is not compatible with --with-dumping=unexec]) -fi - 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 && @@ -2088,48 +2057,6 @@ AC_SUBST([FIND_DELETE]) PAXCTL_dumped= PAXCTL_notdumped= -if test $with_unexec = yes && test $opsys = gnu-linux; then - if test "${SETFATTR+set}" != set; then - AC_CACHE_CHECK([for setfattr], - [emacs_cv_prog_setfattr], - [touch conftest.tmp - if (setfattr -n user.pax.flags conftest.tmp) >/dev/null 2>&1; then - emacs_cv_prog_setfattr=yes - else - emacs_cv_prog_setfattr=no - fi]) - if test "$emacs_cv_prog_setfattr" = yes; then - PAXCTL_notdumped='$(SETFATTR) -n user.pax.flags -v er' - SETFATTR=setfattr - else - SETFATTR= - fi - fi - case $opsys,$PAXCTL_notdumped,$emacs_uname_r in - gnu-linux,,* | netbsd,,[0-7].*) - AC_PATH_PROG([PAXCTL], [paxctl], [], - [$PATH$PATH_SEPARATOR/sbin$PATH_SEPARATOR/usr/sbin]) - if test -n "$PAXCTL"; then - if test "$opsys" = netbsd; then - PAXCTL_dumped='$(PAXCTL) +a' - PAXCTL_notdumped=$PAXCTL_dumped - else - AC_MSG_CHECKING([whether binaries have a PT_PAX_FLAGS header]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], - [if $PAXCTL -v conftest$EXEEXT >/dev/null 2>&1; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - PAXCTL= - fi]) - if test -n "$PAXCTL"; then - PAXCTL_dumped='$(PAXCTL) -zex' - PAXCTL_notdumped='$(PAXCTL) -r' - fi - fi - fi;; - esac -fi AC_SUBST([PAXCTL_dumped]) AC_SUBST([PAXCTL_notdumped]) AC_SUBST([SETFATTR]) @@ -2196,37 +2123,6 @@ else ac_link="$ac_link $NON_GCC_LINK_TEST_OPTIONS" fi -dnl On some platforms using GNU ld, linking temacs needs -znocombreloc. -dnl Although this has something to do with dumping, the details are unknown. -dnl If the flag is used but not needed, -dnl Emacs should still work (albeit a bit more slowly), -dnl so use the flag everywhere that it is supported. -dnl When testing whether the flag works, treat GCC specially -dnl since it just gives a non-fatal 'unrecognized option' -dnl if not built to support GNU ld. -if test "$GCC" = yes; then - LDFLAGS_NOCOMBRELOC="-Wl,-znocombreloc" -else - LDFLAGS_NOCOMBRELOC="-znocombreloc" -fi - -AC_CACHE_CHECK([for -znocombreloc], [emacs_cv_znocombreloc], - [if test $with_unexec = no; then - emacs_cv_znocombreloc='not needed' - else - save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS $LDFLAGS_NOCOMBRELOC" - AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], - [emacs_cv_znocombreloc=yes], [emacs_cv_znocombreloc=no]) - LDFLAGS=$save_LDFLAGS - fi]) - -case $emacs_cv_znocombreloc in - no*) - LDFLAGS_NOCOMBRELOC= ;; -esac - - AC_CACHE_CHECK([whether addresses are sanitized], [emacs_cv_sanitize_address], [AC_COMPILE_IFELSE( @@ -2242,48 +2138,8 @@ AC_CACHE_CHECK([whether addresses are sanitized], [emacs_cv_sanitize_address=yes], [emacs_cv_sanitize_address=no])]) -if test $with_unexec = yes; then - AC_DEFINE([HAVE_UNEXEC], [1], [Define if Emacs supports unexec.]) - if test "$emacs_cv_sanitize_address" = yes; then - AC_MSG_WARN([[Addresses are sanitized; suggest --without-unexec]]) - fi -fi - - -UNEXEC_OBJ= -test $with_unexec = yes && -case "$opsys" in - # MSDOS uses unexcoff.o - aix4-2) - UNEXEC_OBJ=unexaix.o - ;; - cygwin) - UNEXEC_OBJ=unexcw.o - ;; - darwin) - UNEXEC_OBJ=unexmacosx.o - ;; - hpux10-20 | hpux11) - UNEXEC_OBJ=unexhp9k800.o - ;; - mingw32) - UNEXEC_OBJ=unexw32.o - ;; - solaris) - # Use the Solaris dldump() function, called from unexsol.c, to dump - # emacs, instead of the generic ELF dump code found in unexelf.c. - # The resulting binary has a complete symbol table, and is better - # for debugging and other observability tools (debuggers, pstack, etc). - UNEXEC_OBJ=unexsol.o - ;; - *) - UNEXEC_OBJ=unexelf.o - ;; -esac -AC_SUBST([UNEXEC_OBJ]) - LD_SWITCH_SYSTEM= -test "$with_unexec" = no || case "$opsys" in +case "$opsys" in freebsd|dragonfly) ## Let 'ld' find image libs and similar things in /usr/local/lib. ## The system compiler, GCC, has apparently been modified to not @@ -2331,22 +2187,6 @@ esac C_SWITCH_MACHINE= -test $with_unexec = yes && -case $canonical in - alpha*) - ## With ELF, make sure that all common symbols get allocated to in the - ## data section. Otherwise, the dump of temacs may miss variables in - ## the shared library that have been initialized. For example, with - ## GNU libc, __malloc_initialized would normally be resolved to the - ## shared library's .bss section, which is fatal. - if test "x$GCC" = "xyes"; then - C_SWITCH_MACHINE="-fno-common" - else - AC_MSG_ERROR([Non-GCC compilers are not supported.]) - fi - ;; -esac - AC_CACHE_CHECK([for flags to work around GCC bug 58416], [emacs_cv_gcc_bug_58416_CFLAGS], [emacs_cv_gcc_bug_58416_CFLAGS='none needed' @@ -3379,21 +3219,6 @@ system_malloc=yes dnl This must be before the test of $ac_cv_func_sbrk below. AC_CHECK_FUNCS_ONCE([sbrk]) -test $with_unexec = yes && -case "$opsys" in - ## darwin ld insists on the use of malloc routines in the System framework. - darwin | mingw32 | nacl | solaris) ;; - cygwin | qnxnto | freebsd) - hybrid_malloc=yes - system_malloc= ;; - *) test "$ac_cv_func_sbrk" = yes && system_malloc=$emacs_cv_sanitize_address;; -esac - -if test "${system_malloc}" != yes && test "${doug_lea_malloc}" != yes \ - && test "${UNEXEC_OBJ}" = unexelf.o; then - hybrid_malloc=yes -fi - GMALLOC_OBJ= HYBRID_MALLOC= if test "${system_malloc}" = "yes"; then @@ -5268,15 +5093,9 @@ if test "${with_native_compilation}" = "default"; then # Check if libgccjit really works. AC_RUN_IFELSE([libgccjit_smoke_test], [], [libgccjit_broken]) fi - if test "$with_unexec" = yes; then - with_native_compilation=no - fi fi if test "${with_native_compilation}" != "no"; then - if test "$with_unexec" = yes; then - AC_MSG_ERROR(['--with-native-compilation' is not compatible with unexec]) - fi if test "${HAVE_ZLIB}" = no; then AC_MSG_ERROR(['--with-native-compilation' requires zlib]) fi @@ -6085,19 +5904,6 @@ dnl No need to check for posix_memalign if aligned_alloc works. AC_CHECK_FUNCS([aligned_alloc posix_memalign], [break]) AC_CHECK_DECLS([aligned_alloc], [], [], [[#include ]]) -case $with_unexec,$canonical in - yes,alpha*) - AC_CHECK_DECL([__ELF__], [], - [AC_MSG_ERROR([Non-ELF systems are not supported on this platform.])]);; -esac - -if test "$with_unexec" = yes && test "$opsys" = "haiku"; then - dnl A serious attempt was actually made to port unexec to Haiku. - dnl Something in libstdc++ seems to prevent it from working. - AC_MSG_ERROR([Haiku is not supported by the legacy unexec dumper. -Please use the portable dumper instead.]) -fi - # Dump loading. Android lacks posix_madvise. AC_CHECK_FUNCS([posix_madvise madvise]) @@ -7543,9 +7349,6 @@ case "$opsys" in ## about 14 to about 34. Setting it high gets us plenty of slop and ## only costs about 1.5K of wasted binary space. headerpad_extra=1000 - if test "$with_unexec" = yes; then - LD_SWITCH_SYSTEM_TEMACS="-fno-pie $LD_SWITCH_SYSTEM_TEMACS -Xlinker -headerpad -Xlinker $headerpad_extra" - fi ## This is here because src/Makefile.in did some extra fiddling around ## with LD_SWITCH_SYSTEM. It seems cleaner to put this in @@ -7571,49 +7374,11 @@ case "$opsys" in x86_64-*-*) LD_SWITCH_SYSTEM_TEMACS="-Wl,-stack,0x00800000 -Wl,-heap,0x00100000 -Wl,-image-base,0x400000000 -Wl,-entry,__start -Wl,-Map,./temacs.map" ;; *) LD_SWITCH_SYSTEM_TEMACS="-Wl,-stack,0x00800000 -Wl,-heap,0x00100000 -Wl,-image-base,0x01000000 -Wl,-entry,__start -Wl,-Map,./temacs.map" ;; esac - ## If they want unexec, disable Windows ASLR for the Emacs binary - if test "$with_dumping" = "unexec"; then - case "$canonical" in - x86_64-*-*) LD_SWITCH_SYSTEM_TEMACS="$LD_SWITCH_SYSTEM_TEMACS -Wl,-disable-dynamicbase -Wl,-disable-high-entropy-va -Wl,-default-image-base-low" ;; - *) LD_SWITCH_SYSTEM_TEMACS="$LD_SWITCH_SYSTEM_TEMACS -Wl,-disable-dynamicbase" ;; - esac - fi ;; *) LD_SWITCH_SYSTEM_TEMACS= ;; esac -# -no-pie or -nopie fixes a temacs segfault on Gentoo, OpenBSD, -# Ubuntu, and other systems with "hardened" GCC configurations for -# some reason (Bug#18784). We don't know why this works, but not -# segfaulting is better than segfaulting. Use ac_c_werror_flag=yes -# when trying the option, otherwise clang keeps warning that it does -# not understand it, and pre-4.6 GCC has a similar problem -# (Bug#20338). Prefer -no-pie to -nopie, as -no-pie is the -# spelling used by GCC 6.1.0 and later (Bug#24682). -AC_CACHE_CHECK( - [for $CC option to disable position independent executables], - [emacs_cv_prog_cc_no_pie], - [if test $with_unexec = no; then - emacs_cv_prog_cc_no_pie='not needed' - else - emacs_save_c_werror_flag=$ac_c_werror_flag - emacs_save_LDFLAGS=$LDFLAGS - ac_c_werror_flag=yes - for emacs_cv_prog_cc_no_pie in -no-pie -nopie no; do - test $emacs_cv_prog_cc_no_pie = no && break - LDFLAGS="$emacs_save_LDFLAGS $emacs_cv_prog_cc_no_pie" - AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [break]) - done - ac_c_werror_flag=$emacs_save_c_werror_flag - LDFLAGS=$emacs_save_LDFLAGS - fi]) -case $emacs_cv_prog_cc_no_pie in - -*) - LD_SWITCH_SYSTEM_TEMACS="$LD_SWITCH_SYSTEM_TEMACS $emacs_cv_prog_cc_no_pie" - ;; -esac - if test x$ac_enable_profiling != x ; then case $opsys in *freebsd | gnu-linux) ;; @@ -7756,7 +7521,7 @@ for opt in ACL BE_APP CAIRO DBUS FREETYPE GCONF GIF GLIB GMP GNUTLS GPM GSETTING case $opt in PDUMPER) val=${with_pdumper} ;; - UNEXEC) val=${with_unexec} ;; + UNEXEC) val=no ;; GLIB) val=${emacs_cv_links_glib} ;; NOTIFY|ACL) eval val=\${${opt}_SUMMARY} ;; TOOLKIT_SCROLL_BARS|X_TOOLKIT) eval val=\${USE_$opt} ;; @@ -7832,7 +7597,6 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D Does Emacs support Xwidgets? ${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} Does Emacs have native lisp compiler? ${HAVE_NATIVE_COMP} Does Emacs use version 2 of the X Input Extension? ${HAVE_XINPUT2} diff --git a/lisp/loadup.el b/lisp/loadup.el index 613833c4184..8307152a2fa 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -57,7 +57,7 @@ ;; Add subdirectories to the load-path for files that might get ;; autoloaded when bootstrapping or running Emacs normally. ;; This is because PATH_DUMPLOADSEARCH is just "../lisp". -(if (or (member dump-mode '("bootstrap" "pbootstrap")) +(if (or (member dump-mode '("pbootstrap")) ;; FIXME this is irritatingly fragile. (and (stringp (nth 4 command-line-args)) (string-match "^unidata-gen\\(\\.elc?\\)?$" @@ -635,8 +635,6 @@ directory got moved. This is set to be a pair in the form of: (error nil)))))) (if dump-mode (let ((output (cond ((equal dump-mode "pdump") "emacs.pdmp") - ((equal dump-mode "dump") "emacs") - ((equal dump-mode "bootstrap") "emacs") ((equal dump-mode "pbootstrap") "bootstrap-emacs.pdmp") (t (error "Unrecognized dump mode %s" dump-mode))))) (when (and (featurep 'native-compile) @@ -680,7 +678,7 @@ directory got moved. This is set to be a pair in the form of: (eq system-type 'android)) ;; Don't bother adding another name if we're just ;; building bootstrap-emacs. - (member dump-mode '("pbootstrap" "bootstrap")))) + (member dump-mode '("pbootstrap")))) (let ((name (format "emacs-%s.%d" emacs-version emacs-build-number)) (exe (if (eq system-type 'windows-nt) ".exe" ""))) (while (string-match "[^-+_.a-zA-Z0-9]+" name) diff --git a/lisp/startup.el b/lisp/startup.el index 3436409a35e..e9618dc9f6a 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1104,7 +1104,7 @@ init-file, or to a default value if loading is not possible." ;; Else, perhaps the user init file was compiled (when (and (equal (file-name-extension user-init-file) "eln") ;; The next test is for builds without native - ;; compilation support or builds with unexec. + ;; compilation support. (boundp 'comp-eln-to-el-h)) (if-let* ((source (gethash (file-name-nondirectory user-init-file) @@ -2523,7 +2523,7 @@ A fancy display is used on graphic displays, normal otherwise." (defalias 'about-emacs #'display-about-screen) (defalias 'display-splash-screen #'display-startup-screen) -;; This avoids byte-compiler warning in the unexec build. +;; This avoids byte-compiler warning in non-pdumper builds. (declare-function pdumper-stats "pdumper.c" ()) (defun command-line-1 (args-left) diff --git a/src/Makefile.in b/src/Makefile.in index c278924ef94..c35fb3a1bc4 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -386,8 +386,6 @@ RUN_TEMACS = ./temacs # Whether builds should contain details. '--no-build-details' or empty. BUILD_DETAILS = @BUILD_DETAILS@ -UNEXEC_OBJ = @UNEXEC_OBJ@ - HAIKU_OBJ = @HAIKU_OBJ@ HAIKU_CXX_OBJ = @HAIKU_CXX_OBJ@ HAIKU_LIBS = @HAIKU_LIBS@ @@ -471,9 +469,9 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ cmds.o casetab.o casefiddle.o indent.o search.o regex-emacs.o undo.o \ alloc.o pdumper.o data.o doc.o editfns.o callint.o \ eval.o floatfns.o fns.o sort.o font.o print.o lread.o $(MODULES_OBJ) \ - syntax.o $(UNEXEC_OBJ) bytecode.o comp.o $(DYNLIB_OBJ) \ - process.o gnutls.o callproc.o \ - region-cache.o sound.o timefns.o atimer.o \ + syntax.o bytecode.o comp.o $(DYNLIB_OBJ) \ + process.o gnutls.o callproc.o \ + region-cache.o sound.o timefns.o atimer.o \ doprnt.o intervals.o textprop.o composite.o xml.o lcms.o $(NOTIFY_OBJ) \ $(XWIDGETS_OBJ) \ profiler.o decompress.o \ diff --git a/src/alloc.c b/src/alloc.c index 4fab0d54248..eb2e9fae783 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -266,7 +266,7 @@ voidfuncptr __MALLOC_HOOK_VOLATILE __malloc_initialize_hook EXTERNALLY_VISIBLE #endif -#if defined DOUG_LEA_MALLOC || defined HAVE_UNEXEC +#if defined DOUG_LEA_MALLOC /* Allocator-related actions to do just before and after unexec. */ @@ -570,15 +570,9 @@ static void mem_delete (struct mem_node *); static void mem_delete_fixup (struct mem_node *); static struct mem_node *mem_find (void *); -/* Addresses of staticpro'd variables. Initialize it to a nonzero - value if we might unexec; otherwise some compilers put it into - BSS. */ +/* Addresses of staticpro'd variables. */ -Lisp_Object const *staticvec[NSTATICS] -#ifdef HAVE_UNEXEC -= {&Vpurify_flag} -#endif - ; +Lisp_Object const *staticvec[NSTATICS]; /* Index of next unused slot in staticvec. */ @@ -631,10 +625,8 @@ mmap_lisp_allowed_p (void) { /* If we can't store all memory addresses in our lisp objects, it's risky to let the heap use mmap and give us addresses from all - over our address space. We also can't use mmap for lisp objects - if we might dump: unexec doesn't preserve the contents of mmapped - regions. */ - return pointers_fit_in_lispobj_p () && !will_dump_with_unexec_p (); + over our address space. */ + return pointers_fit_in_lispobj_p (); } #endif @@ -1071,11 +1063,7 @@ lisp_free (void *block) BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ /* Byte alignment of storage blocks. */ -#ifdef HAVE_UNEXEC -# define BLOCK_ALIGN (1 << 10) -#else /* !HAVE_UNEXEC */ # define BLOCK_ALIGN (1 << 15) -#endif static_assert (POWER_OF_2 (BLOCK_ALIGN)); /* Use aligned_alloc if it or a simple substitute is available. diff --git a/src/buffer.c b/src/buffer.c index 2955ee6399b..663a47ec72f 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -4892,47 +4892,6 @@ init_buffer (void) { Lisp_Object temp; -#ifdef USE_MMAP_FOR_BUFFERS - if (dumped_with_unexec_p ()) - { - Lisp_Object tail, buffer; - -#ifndef WINDOWSNT - /* These must be reset in the dumped Emacs, to avoid stale - references to mmap'ed memory from before the dump. - - WINDOWSNT doesn't need this because it doesn't track mmap'ed - regions by hand (see w32heap.c, which uses system APIs for - that purpose), and thus doesn't use mmap_regions. */ - mmap_regions = NULL; - mmap_fd = -1; -#endif - - /* The dumped buffers reference addresses of buffer text - recorded by temacs, that cannot be used by the dumped Emacs. - We map new memory for their text here. - - Implementation notes: the buffers we carry from temacs are: - " prin1", "*scratch*", " *Minibuf-0*", "*Messages*", and - " *code-conversion-work*". They are created by - init_buffer_once and init_window_once (which are not called - in the dumped Emacs), and by the first call to coding.c - routines. Since FOR_EACH_LIVE_BUFFER only walks the buffers - in Vbuffer_alist, any buffer we carry from temacs that is - not in the alist (a.k.a. "magic invisible buffers") should - be handled here explicitly. */ - FOR_EACH_LIVE_BUFFER (tail, buffer) - { - struct buffer *b = XBUFFER (buffer); - b->text->beg = NULL; - enlarge_buffer_text (b, 0); - } - /* The " prin1" buffer is not in Vbuffer_alist. */ - XBUFFER (Vprin1_to_string_buffer)->text->beg = NULL; - enlarge_buffer_text (XBUFFER (Vprin1_to_string_buffer), 0); - } -#endif /* USE_MMAP_FOR_BUFFERS */ - AUTO_STRING (scratch, "*scratch*"); Fset_buffer (Fget_buffer_create (scratch, Qnil)); if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) diff --git a/src/conf_post.h b/src/conf_post.h index f2353803074..8d523c62eee 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -93,30 +93,6 @@ typedef bool bool_bf; # define ADDRESS_SANITIZER false #endif -#ifdef emacs -/* We include stdlib.h here, because Gnulib's stdlib.h might redirect - 'free' to its replacement, and we want to avoid that in unexec - builds. Including it here will render its inclusion after config.h - a no-op. */ -# if (defined DARWIN_OS && defined HAVE_UNEXEC) || defined HYBRID_MALLOC -# include -# endif -#endif - -#if defined DARWIN_OS && defined emacs && defined HAVE_UNEXEC -# undef malloc -# define malloc unexec_malloc -# undef realloc -# define realloc unexec_realloc -# undef free -# define free unexec_free - -extern void *unexec_malloc (size_t); -extern void *unexec_realloc (void *, size_t); -extern void unexec_free (void *); - -#endif - /* If HYBRID_MALLOC is defined (e.g., on Cygwin), emacs will use gmalloc before dumping and the system malloc after dumping. hybrid_malloc and friends, defined in gmalloc.c, are wrappers that diff --git a/src/emacs.c b/src/emacs.c index bdd9eee10c4..4e6f286d888 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -196,11 +196,6 @@ bool running_asynch_code; bool display_arg; #endif -#if defined GNU_LINUX && defined HAVE_UNEXEC -/* The gap between BSS end and heap start as far as we can tell. */ -static uintmax_t heap_bss_diff; -#endif - /* To run as a background daemon under Cocoa or Windows, we must do a fork+exec, not a simple fork. @@ -912,14 +907,6 @@ load_pdump (int argc, char **argv, char *dump_file) #endif ; - /* TODO: maybe more thoroughly scrub process environment in order to - make this use case (loading a dump file in an unexeced emacs) - possible? Right now, we assume that things we don't touch are - zero-initialized, and in an unexeced Emacs, this assumption - doesn't hold. */ - if (initialized) - fatal ("cannot load dump file in unexeced Emacs"); - /* Look for an explicitly-specified dump file. */ const char *path_exec = PATH_EXEC; dump_file = NULL; @@ -1318,53 +1305,34 @@ main (int argc, char **argv) #endif /* Look for this argument first, before any heap allocation, so we - can set heap flags properly if we're going to unexec. */ + can set heap flags properly if we're going to dump. */ if (!initialized && temacs) { -#ifdef HAVE_UNEXEC - 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 HAVE_UNEXEC 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 (); + will_dump_with_pdumper_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 { eassert (!temacs); -#ifndef HAVE_UNEXEC eassert (!initialized); -#endif #ifdef HAVE_PDUMPER if (!initialized) attempt_load_pdump = true; #endif } -#ifdef HAVE_UNEXEC - if (!will_dump_with_unexec_p ()) - gflags.will_not_unexec_ = true; -#endif - #ifdef WINDOWSNT /* Grab our malloc arena space now, before anything important happens. This relies on the static heap being needed only in @@ -1427,25 +1395,12 @@ main (int argc, char **argv) argc = maybe_disable_address_randomization (argc, argv); -#if defined GNU_LINUX && defined HAVE_UNEXEC - if (!initialized) - { - char *heap_start = my_heap_start (); - heap_bss_diff = heap_start - max (my_endbss, my_endbss_static); - } -#endif #ifdef RUN_TIME_REMAP if (initialized) run_time_remap (argv[0]); #endif -/* If using unexmacosx.c (set by s/darwin.h), we must do this. */ -#if defined DARWIN_OS && defined HAVE_UNEXEC - if (!initialized) - unexec_init_emacs_zone (); -#endif - init_standard_fds (); atexit (close_output_streams); @@ -1627,10 +1582,7 @@ main (int argc, char **argv) #endif /* MSDOS */ /* Set locale, so that initial error messages are localized properly. - However, skip this if LC_ALL is "C", as it's not needed in that case. - Skipping helps if dumping with unexec, to ensure that the dumped - Emacs does not have its system locale tables initialized, as that - might cause screwups when the dumped Emacs starts up. */ + However, skip this if LC_ALL is "C", as it's not needed in that case. */ char *lc_all = getenv ("LC_ALL"); if (! (lc_all && strcmp (lc_all, "C") == 0)) { @@ -3155,117 +3107,6 @@ shut_down_emacs (int sig, Lisp_Object stuff) } - -#ifdef HAVE_UNEXEC - -#include "unexec.h" - -DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0, - doc: /* Dump current state of Emacs into executable file FILENAME. -Take symbols from SYMFILE (presumably the file you executed to run Emacs). -This is used in the file `loadup.el' when building Emacs. - -You must run Emacs in batch mode in order to dump it. */) - (Lisp_Object filename, Lisp_Object symfile) -{ - Lisp_Object tem; - Lisp_Object symbol; - specpdl_ref count = SPECPDL_INDEX (); - - check_pure_size (); - - if (! noninteractive) - error ("Dumping Emacs works only in batch mode"); - - 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 HAVE_UNEXEC - - /* Warn if the gap between BSS end and heap start is larger than this. */ -# define MAX_HEAP_BSS_DIFF (1024 * 1024) - - if (heap_bss_diff > MAX_HEAP_BSS_DIFF) - fprintf (stderr, - ("**************************************************\n" - "Warning: Your system has a gap between BSS and the\n" - "heap (%"PRIuMAX" bytes). This usually means that exec-shield\n" - "or something similar is in effect. The dump may\n" - "fail because of this. See the section about\n" - "exec-shield in etc/PROBLEMS for more information.\n" - "**************************************************\n"), - heap_bss_diff); -# endif - - /* Bind `command-line-processed' to nil before dumping, - so that the dumped Emacs will process its command line - and set up to work with X windows if appropriate. */ - symbol = Qcommand_line_processed; - specbind (symbol, Qnil); - - CHECK_STRING (filename); - filename = Fexpand_file_name (filename, Qnil); - filename = ENCODE_FILE (filename); - if (!NILP (symfile)) - { - CHECK_STRING (symfile); - if (SCHARS (symfile)) - { - symfile = Fexpand_file_name (symfile, Qnil); - symfile = ENCODE_FILE (symfile); - } - } - - tem = Vpurify_flag; - Vpurify_flag = Qnil; - -# ifdef HYBRID_MALLOC - { - static char const fmt[] = "%d of %d static heap bytes used"; - char buf[sizeof fmt + 2 * (INT_STRLEN_BOUND (int) - 2)]; - int max_usage = max_bss_sbrk_ptr - bss_sbrk_buffer; - sprintf (buf, fmt, max_usage, STATIC_HEAP_SIZE); - /* Don't log messages, because at this point buffers cannot be created. */ - message1_nolog (buf); - } -# endif - - fflush (stdout); - /* Tell malloc where start of impure now is. */ - /* Also arrange for warnings when nearly out of space. */ -# if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC && !defined WINDOWSNT - /* On Windows, this was done before dumping, and that once suffices. - Meanwhile, my_edata is not valid on Windows. */ - memory_warnings (my_edata, malloc_warning); -# endif - - struct gflags old_gflags = gflags; - gflags.will_dump_ = false; - gflags.will_dump_with_unexec_ = false; - gflags.dumped_with_unexec_ = true; - - alloc_unexec_pre (); - - unexec (SSDATA (filename), !NILP (symfile) ? SSDATA (symfile) : 0); - - alloc_unexec_post (); - - gflags = old_gflags; - -# ifdef WINDOWSNT - Vlibrary_cache = Qnil; -# endif - - Vpurify_flag = tem; - - return unbind_to (count, Qnil); -} - -#endif - /* Recover from setlocale (LC_ALL, ""). */ void @@ -3565,10 +3406,6 @@ syms_of_emacs (void) DEFSYM (Qcommand_line_processed, "command-line-processed"); DEFSYM (Qsafe_magic, "safe-magic"); -#ifdef HAVE_UNEXEC - defsubr (&Sdump_emacs); -#endif - defsubr (&Skill_emacs); defsubr (&Sinvocation_name); diff --git a/src/lastfile.c b/src/lastfile.c index 48d3ac78634..c6baad4ac01 100644 --- a/src/lastfile.c +++ b/src/lastfile.c @@ -42,14 +42,3 @@ along with GNU Emacs. If not, see . */ || defined WINDOWSNT || defined CYGWIN || defined DARWIN_OS) char my_edata[] = "End of Emacs initialized data"; #endif - -#ifdef HAVE_UNEXEC - -/* Help unexec locate the end of the .bss area used by Emacs (which - isn't always a separate section in NT executables). */ -char my_endbss[1]; - -static char _my_endbss[1]; -char * my_endbss_static = _my_endbss; - -#endif diff --git a/src/lisp.h b/src/lisp.h index 832a1755c04..a7b84b25b81 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -640,20 +640,12 @@ extern struct gflags dump. */ bool dumped_with_pdumper_ : 1; #endif -#ifdef HAVE_UNEXEC - bool will_dump_with_unexec_ : 1; - /* 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; INLINE bool will_dump_p (void) { -#if HAVE_PDUMPER || defined HAVE_UNEXEC +#if HAVE_PDUMPER return gflags.will_dump_; #else return false; @@ -663,7 +655,7 @@ will_dump_p (void) INLINE bool will_bootstrap_p (void) { -#if HAVE_PDUMPER || defined HAVE_UNEXEC +#if HAVE_PDUMPER return gflags.will_bootstrap_; #else return false; @@ -690,39 +682,6 @@ dumped_with_pdumper_p (void) #endif } -INLINE bool -will_dump_with_unexec_p (void) -{ -#ifdef HAVE_UNEXEC - return gflags.will_dump_with_unexec_; -#else - return false; -#endif -} - -INLINE bool -dumped_with_unexec_p (void) -{ -#ifdef HAVE_UNEXEC - return gflags.dumped_with_unexec_; -#else - return false; -#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 HAVE_UNEXEC - return gflags.will_not_unexec_; -#else - return true; -#endif -} - /* Defined in floatfns.c. */ extern double extract_float (Lisp_Object); @@ -3443,14 +3402,10 @@ CHECK_SUBR (Lisp_Object x) /* If we're not dumping using the legacy dumper and we might be using the portable dumper, try to bunch all the subr structures together for more efficient dump loading. */ -#ifndef HAVE_UNEXEC -# ifdef DARWIN_OS -# define SUBR_SECTION_ATTRIBUTE ATTRIBUTE_SECTION ("__DATA,subrs") -# else -# define SUBR_SECTION_ATTRIBUTE ATTRIBUTE_SECTION (".subrs") -# endif +#ifdef DARWIN_OS +# define SUBR_SECTION_ATTRIBUTE ATTRIBUTE_SECTION ("__DATA,subrs") #else -# define SUBR_SECTION_ATTRIBUTE +# define SUBR_SECTION_ATTRIBUTE ATTRIBUTE_SECTION (".subrs") #endif /* Define a built-in function for calling from Lisp. @@ -4492,8 +4447,6 @@ extern void mark_objects (Lisp_Object *, ptrdiff_t); #if defined REL_ALLOC && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC extern void refill_memory_reserve (void); #endif -extern void alloc_unexec_pre (void); -extern void alloc_unexec_post (void); extern void mark_c_stack (char const *, char const *); extern void flush_stack_call_func1 (void (*func) (void *arg), void *arg); extern void mark_memory (void const *start, void const *end); @@ -4927,14 +4880,6 @@ void do_debug_on_call (Lisp_Object code, specpdl_ref count); Lisp_Object funcall_general (Lisp_Object fun, ptrdiff_t numargs, Lisp_Object *args); -/* Defined in unexmacosx.c. */ -#if defined DARWIN_OS && defined HAVE_UNEXEC -extern void unexec_init_emacs_zone (void); -extern void *unexec_malloc (size_t); -extern void *unexec_realloc (void *, size_t); -extern void unexec_free (void *); -#endif - /* The definition of Lisp_Module_Function depends on emacs-module.h, so we don't define it here. It's defined in emacs-module.c. */ diff --git a/src/pdumper.c b/src/pdumper.c index c8baa311854..88e8e810adc 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -4143,12 +4143,6 @@ types. */) "contributing a patch to Emacs."); #endif - if (will_dump_with_unexec_p ()) - error ("This Emacs instance was started under the assumption " - "that it would be dumped with unexec, not the portable " - "dumper. Dumping with the portable dumper may produce " - "unexpected results."); - if (!main_thread_p (current_thread)) error ("This function can be called only in the main thread"); diff --git a/src/process.c b/src/process.c index b71ba3daf2d..dcf08fd9b57 100644 --- a/src/process.c +++ b/src/process.c @@ -8620,50 +8620,39 @@ init_process_emacs (int sockfd) inhibit_sentinels = 0; -#ifdef HAVE_UNEXEC - /* Clear child_signal_read_fd and child_signal_write_fd after dumping, - lest wait_reading_process_output should select on nonexistent file - descriptors which existed in the build process. */ - child_signal_read_fd = -1; - child_signal_write_fd = -1; -#endif /* HAVE_UNEXEC */ - - if (!will_dump_with_unexec_p ()) - { #if defined HAVE_GLIB && !defined WINDOWSNT - /* Tickle Glib's child-handling code. Ask Glib to install a - watch source for Emacs itself which will initialize glib's - private SIGCHLD handler, allowing catch_child_signal to copy - it into lib_child_handler. This is a hacky workaround to get - glib's g_unix_signal_handler into lib_child_handler. + /* Tickle Glib's child-handling code. Ask Glib to install a + watch source for Emacs itself which will initialize glib's + private SIGCHLD handler, allowing catch_child_signal to copy + it into lib_child_handler. This is a hacky workaround to get + glib's g_unix_signal_handler into lib_child_handler. - In Glib 2.37.5 (2013), commit 2e471acf changed Glib to - always install a signal handler when g_child_watch_source_new - is called and not just the first time it's called, and to - reset signal handlers to SIG_DFL when it no longer has a - watcher on that signal. Arrange for Emacs's signal handler - to be reinstalled even if this happens. + In Glib 2.37.5 (2013), commit 2e471acf changed Glib to + always install a signal handler when g_child_watch_source_new + is called and not just the first time it's called, and to + reset signal handlers to SIG_DFL when it no longer has a + watcher on that signal. Arrange for Emacs's signal handler + to be reinstalled even if this happens. - In Glib 2.73.2 (2022), commit f615eef4 changed Glib again, - to not install a signal handler if the system supports - pidfd_open and waitid (as in Linux kernel 5.3+). The hacky - workaround is not needed in this case. */ - GSource *source = g_child_watch_source_new (getpid ()); + In Glib 2.73.2 (2022), commit f615eef4 changed Glib again, + to not install a signal handler if the system supports + pidfd_open and waitid (as in Linux kernel 5.3+). The hacky + workaround is not needed in this case. */ + GSource *source = g_child_watch_source_new (getpid ()); + catch_child_signal (); + g_source_unref (source); + + if (lib_child_handler != dummy_handler) + { + /* The hacky workaround is needed on this platform. */ + signal_handler_t lib_child_handler_glib = lib_child_handler; catch_child_signal (); - g_source_unref (source); - - if (lib_child_handler != dummy_handler) - { - /* The hacky workaround is needed on this platform. */ - signal_handler_t lib_child_handler_glib = lib_child_handler; - catch_child_signal (); - eassert (lib_child_handler == dummy_handler); - lib_child_handler = lib_child_handler_glib; - } -#else - catch_child_signal (); -#endif + eassert (lib_child_handler == dummy_handler); + lib_child_handler = lib_child_handler_glib; } +#else + catch_child_signal (); +#endif #ifdef HAVE_SETRLIMIT /* Don't allocate more than FD_SETSIZE file descriptors for Emacs itself. */ diff --git a/src/sysdep.c b/src/sysdep.c index bb4892af4af..e0ec74d8364 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -165,9 +165,7 @@ maybe_disable_address_randomization (int argc, char **argv) if (argc < 2 || strcmp (argv[1], aslr_disabled_option) != 0) { - /* If dumping via unexec, ASLR must be disabled, as otherwise - data may be scattered and undumpable as a simple executable. - If pdumping, disabling ASLR lessens differences in the .pdmp file. */ + /* If pdumping, disabling ASLR lessens differences in the .pdmp file. */ bool disable_aslr = will_dump_p (); # ifdef __PPC64__ disable_aslr = true; @@ -2036,12 +2034,6 @@ init_signals (void) main_thread_id = pthread_self (); #endif - /* Don't alter signal handlers if dumping with unexec. On some - machines, changing signal handlers sets static data that would make - signals fail to work right when the dumped Emacs is run. */ - if (will_dump_with_unexec_p ()) - return; - sigfillset (&process_fatal_action.sa_mask); process_fatal_action.sa_handler = deliver_fatal_signal; process_fatal_action.sa_flags = emacs_sigaction_flags (); diff --git a/src/timefns.c b/src/timefns.c index f16a34d651b..520a48f2b9b 100644 --- a/src/timefns.c +++ b/src/timefns.c @@ -318,37 +318,8 @@ tzlookup (Lisp_Object zone, bool settz) void init_timefns (void) { -#ifdef HAVE_UNEXEC - /* A valid but unlikely setting for the TZ environment variable. - It is OK (though a bit slower) if the user chooses this value. */ - static char dump_tz_string[] = "TZ=UtC0"; - - /* When just dumping out, set the time zone to a known unlikely value - and skip the rest of this function. */ - if (will_dump_with_unexec_p ()) - { - xputenv (dump_tz_string); - tzset (); - return; - } -#endif - char *tz = getenv ("TZ"); -#ifdef HAVE_UNEXEC - /* If the execution TZ happens to be the same as the dump TZ, - change it to some other value and then change it back, - to force the underlying implementation to reload the TZ info. - This is needed on implementations that load TZ info from files, - since the TZ file contents may differ between dump and execution. */ - if (tz && strcmp (tz, &dump_tz_string[tzeqlen]) == 0) - { - ++*tz; - tzset (); - --*tz; - } -#endif - /* Set the time zone rule now, so that the call to putenv is done before multiple threads are active. */ tzlookup (tz ? build_string (tz) : Qwall, true); diff --git a/src/w32heap.c b/src/w32heap.c index 601686f5331..c5777622c56 100644 --- a/src/w32heap.c +++ b/src/w32heap.c @@ -617,31 +617,6 @@ sys_calloc (size_t number, size_t size) return ptr; } -#if defined HAVE_UNEXEC && defined ENABLE_CHECKING -void -report_temacs_memory_usage (void) -{ - DWORD blocks_used = 0; - size_t large_mem_used = 0; - int i; - - for (i = 0; i < blocks_number; i++) - if (blocks[i].occupied) - { - blocks_used++; - large_mem_used += blocks[i].size; - } - - /* Emulate 'message', which writes to stderr in non-interactive - sessions. */ - fprintf (stderr, - "Dump memory usage: Heap: %" PRIu64 " Large blocks(%lu/%lu): %" PRIu64 "/%" PRIu64 "\n", - (unsigned long long)committed, blocks_used, blocks_number, - (unsigned long long)large_mem_used, - (unsigned long long)(dumped_data + DUMPED_HEAP_SIZE - bc_limit)); -} -#endif - /* Emulate getpagesize. */ int getpagesize (void) diff --git a/src/w32heap.h b/src/w32heap.h index 24b02fabbfc..901c9b5a41e 100644 --- a/src/w32heap.h +++ b/src/w32heap.h @@ -1,4 +1,4 @@ -/* Heap management routines (including unexec) for GNU Emacs on Windows NT. +/* Heap management routines for GNU Emacs on Windows NT. Copyright (C) 1994, 2001-2024 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/src/w32image.c b/src/w32image.c index da4d6843ba9..02700338715 100644 --- a/src/w32image.c +++ b/src/w32image.c @@ -634,6 +634,4 @@ syms_of_w32image (void) void globals_of_w32image (void) { - /* This is only needed in an unexec build. */ - memset (&last_encoder, 0, sizeof last_encoder); }