],
[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
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])
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 &&
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])
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(
[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
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'
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
# 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
AC_CHECK_FUNCS([aligned_alloc posix_memalign], [break])
AC_CHECK_DECLS([aligned_alloc], [], [], [[#include <stdlib.h>]])
-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])
## 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
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) ;;
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} ;;
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}
;; 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?\\)?$"
(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)
(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)
;; 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)
(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)
# 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@
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 \
#endif
-#if defined DOUG_LEA_MALLOC || defined HAVE_UNEXEC
+#if defined DOUG_LEA_MALLOC
/* Allocator-related actions to do just before and after unexec. */
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. */
{
/* 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
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.
{
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)))
# define ADDRESS_SANITIZER false
#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
+ accomplish this. */
+#ifdef HYBRID_MALLOC
+#ifdef emacs
+#undef malloc
+#define malloc hybrid_malloc
+#undef realloc
+#define realloc hybrid_realloc
+#undef aligned_alloc
+#define aligned_alloc hybrid_aligned_alloc
+#undef calloc
+#define calloc hybrid_calloc
+#undef free
+#define free hybrid_free
+
+extern void *hybrid_malloc (size_t);
+extern void *hybrid_calloc (size_t, size_t);
+extern void hybrid_free (void *);
+extern void *hybrid_aligned_alloc (size_t, size_t);
+extern void *hybrid_realloc (void *, size_t);
+#endif /* emacs */
+#endif /* HYBRID_MALLOC */
+
/* We have to go this route, rather than the old hpux9 approach of
renaming the functions via macros. The system's stdlib.h has fully
prototyped declarations, which yields a conflicting definition of
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.
#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;
#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
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);
#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))
{
}
-\f
-#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
-
\f
/* Recover from setlocale (LC_ALL, ""). */
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);
|| 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
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;
INLINE bool
will_bootstrap_p (void)
{
-#if HAVE_PDUMPER || defined HAVE_UNEXEC
+#if HAVE_PDUMPER
return gflags.will_bootstrap_;
#else
return false;
#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);
/* 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.
#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);
Lisp_Object funcall_general (Lisp_Object fun,
ptrdiff_t numargs, Lisp_Object *args);
-/* Defined in unexmacosx.c. */
-#if defined DARWIN_OS && defined HAVE_UNEXEC
-/* Redirect calls to malloc, realloc and free to a macOS zone memory allocator.
- FIXME: Either also redirect unexec_aligned_alloc and unexec_calloc,
- or fix this comment to explain why those two redirections are not needed. */
-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 *);
-# ifndef UNEXMACOSX_C
-# include <stdlib.h>
-# undef malloc
-# undef realloc
-# undef free
-# define malloc unexec_malloc
-# define realloc unexec_realloc
-# define free unexec_free
-# endif
-#endif
-
-/* Defined in gmalloc.c. */
-#ifdef HYBRID_MALLOC
-/* Redirect calls to malloc and friends to a hybrid allocator that
- uses gmalloc before dumping and the system malloc after dumping.
- This can be useful on Cygwin, for example. */
-extern void *hybrid_aligned_alloc (size_t, size_t);
-extern void *hybrid_calloc (size_t, size_t);
-extern void *hybrid_malloc (size_t);
-extern void *hybrid_realloc (void *, size_t);
-extern void hybrid_free (void *);
-# include <stdlib.h>
-# undef aligned_alloc
-# undef calloc
-# undef malloc
-# undef realloc
-# undef free
-# define aligned_alloc hybrid_aligned_alloc
-# define calloc hybrid_calloc
-# define malloc hybrid_malloc
-# define realloc hybrid_realloc
-# define free hybrid_free
-#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. */
"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");
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 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.
+
+ 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 ());
+ catch_child_signal ();
+ g_source_unref (source);
- if (!will_dump_with_unexec_p ())
+ if (lib_child_handler != dummy_handler)
{
-#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.
-
- 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 ());
+ /* 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;
- }
+ eassert (lib_child_handler == dummy_handler);
+ lib_child_handler = lib_child_handler_glib;
+ }
#else
- catch_child_signal ();
+ catch_child_signal ();
#endif
- }
#ifdef HAVE_SETRLIMIT
/* Don't allocate more than FD_SETSIZE file descriptors for Emacs itself. */
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;
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 ();
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);
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)
-/* Heap management routines (including unexec) for GNU Emacs on Windows NT.
- Copyright (C) 1994, 2001-2025 Free Software Foundation, Inc.
+/* 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.
void
globals_of_w32image (void)
{
- /* This is only needed in an unexec build. */
- memset (&last_encoder, 0, sizeof last_encoder);
}