From 35fccb233f51636467ddb58c2a7b05fb28b6eb1d Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 20 Feb 2025 14:04:59 +0800 Subject: [PATCH] Port to modern GCC and pdumper on MS-DOS * config.bat (mvOk): Protoize. (djgppOk): Include sys/version.h for _DJGPP_MINOR. * lisp/loadup.el: If system-type is ms-dos, dump bootstrap-emacs as b-emacs.dmp. * msdos/INSTALL: Document new versions of tools that have been verified successfully to compile Emacs. * msdos/emacs.djl: New linker script that arranges to link symbols in `.subrs' in a contiguous part of data, as the DJGPP runtime appears to treat any non-data and non-text section as allocatable. * msdos/mainmake.v2 (install): Install emacs.dmp alongside emacs.exe. * msdos/sed1v2.inp (CFLAGS): Define to -O2 -g3. (LDFLAGS): Provide the said linker script. (HAVE_PDUMPER): Define to yes. (UNEXEC_OBJ, PAXCTL_dumped, PAXCTL_notdumped): Delete. (DUMPING): Set to pdumper. (MAKE_PDUMPER_FINGERPRINT): Don't erase this variable. Don't stubify or set minstack. Remove native-comp specific directives. Don't remove temacs prior to copying and replace `pdmp' extension with DOS-conformant `dmp'. * msdos/sed2v2.inp (HAVE_UNEXEC): Remove definition. (HAVE_PDUMPER): Define to 1. * msdos/sed6.inp (top_srcdir): Define appropriately. * msdos/sedlibmk.inp (HAVE_BLKCNT_T): Define to 1. * src/emacs.c (load_pdump) [MSDOS]: Use `dmp' suffix. * src/pdumper.c (Fdump_emacs_portable) [MSDOS]: Replace ".pdmp" suffixes with ".dmp". (cherry picked from commit c22957c4bf7dd25857a44946169c4818996a49d9) --- config.bat | 5 ++- lisp/loadup.el | 5 ++- msdos/INSTALL | 11 ++---- msdos/emacs.djl | 95 ++++++++++++++++++++++++++++++++++++++++++++++ msdos/mainmake.v2 | 1 + msdos/sed1v2.inp | 24 ++++-------- msdos/sed2v2.inp | 2 +- msdos/sed6.inp | 1 + msdos/sedlibmk.inp | 1 + src/emacs.c | 4 ++ src/lisp.h | 5 ++- src/pdumper.c | 20 +++++++++- 12 files changed, 142 insertions(+), 32 deletions(-) create mode 100644 msdos/emacs.djl diff --git a/config.bat b/config.bat index fba0ac2925f..393c950074e 100644 --- a/config.bat +++ b/config.bat @@ -94,7 +94,7 @@ Goto End :mvOk rm -f junk.2 Echo Checking whether 'gcc' is available... -echo main(){} >junk.c +echo int main(void){} >junk.c gcc -c junk.c if exist junk.o goto gccOk Echo To configure 'Emacs' you need to have 'gcc'! @@ -107,7 +107,8 @@ If Not "%DJGPP%" == "" goto djgppOk Echo To compile 'Emacs' under MS-DOS you MUST have DJGPP installed! Goto End :djgppOk -echo int main() >junk.c +echo #include "sys/version.h" >junk.c +echo int main() >>junk.c echo #ifdef __DJGPP__ >>junk.c echo {return (__DJGPP__)*10 + (__DJGPP_MINOR__);} >>junk.c echo #else >>junk.c diff --git a/lisp/loadup.el b/lisp/loadup.el index cf253980f9f..934e5bf4068 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -600,7 +600,10 @@ 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 "pbootstrap") "bootstrap-emacs.pdmp") + ((equal dump-mode "pbootstrap") + (if (eq system-type 'ms-dos) + "b-emacs.pdmp" + "bootstrap-emacs.pdmp")) (t (error "Unrecognized dump mode %s" dump-mode))))) (when (and (featurep 'native-compile) (equal dump-mode "pdump")) diff --git a/msdos/INSTALL b/msdos/INSTALL index ffc1fee84f0..c5fd16aa9ac 100644 --- a/msdos/INSTALL +++ b/msdos/INSTALL @@ -19,14 +19,9 @@ the necessary utilities; search for "MS-DOS". The configuration step (see below) will test for these utilities and will refuse to continue if any of them isn't found. -You should carefully choose the version of GCC you use to build Emacs, -because recent versions of GCC don't support building Emacs very well. -The main issue is the debug info: the DJGPP build of Emacs must use -the COFF debug info. GCC support for COFF debug info was steadily -deteriorating since GCC 5, and GCC 8.1 officially stopped supporting -the -gcoff switch, which the Emacs build process needs. We recommend -using GCC 3.4.X and Binutils 2.26; GDB 7.2 is capable to debug an -Emacs binary built by this combination. +Binutils 2.35.1 with GCC 14.2.0 have been verified to be capable of +compiling the MS-DOS port of Emacs, and GDB 8.0.1, to be capable of +debugging Emacs executables produced by this configuration. Bootstrapping Emacs or recompiling Lisp files in the `lisp' subdirectory using the various targets in the lisp/Makefile file diff --git a/msdos/emacs.djl b/msdos/emacs.djl new file mode 100644 index 00000000000..3f6e0852b32 --- /dev/null +++ b/msdos/emacs.djl @@ -0,0 +1,95 @@ +/* Modified version of the default DJGPP linker script for GNU -*- c -*- + Emacs. */ + +/* Default linker script, for normal executables */ +/* Copyright (C) 2014 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("coff-go32-exe") +ENTRY (start) +SECTIONS +{ + .text 0x1000+SIZEOF_HEADERS : { + *(.text) + *(.text.*) + *(.gnu.linkonce.t*) + *(.const*) + *(.ro*) + *(.gnu.linkonce.r*) + etext = . ; PROVIDE(_etext = .) ; + . = ALIGN(0x200); + } + .data ALIGN(0x200) : { + djgpp_first_ctor = . ; + *(SORT(.ctors.*)) + *(.ctor) + *(.ctors) + djgpp_last_ctor = . ; + djgpp_first_dtor = . ; + *(SORT(.dtors.*)) + *(.dtor) + *(.dtors) + djgpp_last_dtor = . ; + __environ = . ; + PROVIDE(_environ = .) ; + LONG(0) ; + *(.data) + *(.data.*) + *(.subrs) + *(.subrs.*) + /* Ugly workaround to prevent entire .bss to have attribute CONTENT */ + /* for C++ executables. */ + *( .bss.*) + *(.gcc_exc*) + ___EH_FRAME_BEGIN__ = . ; + *(.eh_fram*) + ___EH_FRAME_END__ = . ; + LONG(0) ; + *(.gnu.linkonce.d*) + edata = . ; PROVIDE(_edata = .) ; + . = ALIGN(0x200); + } + .bss SIZEOF(.data) + ADDR(.data) : + { + *(.bss .gnu.linkonce.b.*) + *(COMMON) + end = . ; PROVIDE(_end = .) ; + . = ALIGN(0x200); + } + /* Discard LTO sections. */ + /DISCARD/ : { *(gnu.lto_*) } + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } +} diff --git a/msdos/mainmake.v2 b/msdos/mainmake.v2 index 03265b59f64..c8990d85e09 100644 --- a/msdos/mainmake.v2 +++ b/msdos/mainmake.v2 @@ -136,6 +136,7 @@ install: all cd .. cd src mv -f emacs.exe ../bin/ + mv -f emacs.dmp ../bin/ cd .. djecho -s "(if (fboundp 'normal-top-level-add-subdirs-to-load-path)" \ " (normal-top-level-add-subdirs-to-load-path))" \ diff --git a/msdos/sed1v2.inp b/msdos/sed1v2.inp index 791d6ab2693..1de2c11a0c4 100644 --- a/msdos/sed1v2.inp +++ b/msdos/sed1v2.inp @@ -22,11 +22,11 @@ s/\.h\.in/.h-in/ /^srcdir *=/s/@[^@\n]*@/./ /^top_srcdir *=/s/@[^@\n]*@/../ /^CC *=/s/@[^@\n]*@/gcc -std=gnu99/ -/^CFLAGS *=/s/@[^@\n]*@/-O2 -gcoff/ +/^CFLAGS *=/s/@[^@\n]*@/-O2 -g3/ /^ALL_CFLAGS *=/s/@[^@\n]*@//g /^ALL_CFLAGS *=/s/ -I\.//g /^CPPFLAGS *=/s|@[^@\n]*@|-I../msdos| -/^LDFLAGS *=/s/@[^@\n]*@// +/^LDFLAGS *=/s/@[^@\n]*@/-T ..\/msdos\/emacs.djl/ /^LIBOBJS *=/s/@[^@\n]*@// /^C_SWITCH_MACHINE *=/s/@C_SWITCH_MACHINE@// /^C_SWITCH_SYSTEM *=/s/@C_SWITCH_SYSTEM@// @@ -60,7 +60,7 @@ s/ *@WEBP_LIBS@// /^JPEG_CFLAGS *=/s/@JPEG_CFLAGS@// /^TIFF_CFLAGS *=/s/@TIFF_CFLAGS@// /^HAVE_NATIVE_COMP *=/s/@HAVE_NATIVE_COMP@/no/ -/^HAVE_PDUMPER *=/s/@HAVE_PDUMPER@/no/ +/^HAVE_PDUMPER *=/s/@HAVE_PDUMPER@/yes/ /^HAVE_BE_APP *=/s/@HAVE_BE_APP@/no/ /^CHECK_STRUCTS *=/s/@CHECK_STRUCTS@// /^RUN_TEMACS \=/s/temacs/temacs.exe/ @@ -166,7 +166,6 @@ s/ *@WEBP_LIBS@// /^GMALLOC_OBJ *=/s/@GMALLOC_OBJ@/gmalloc.o/ /^VMLIMIT_OBJ *=/s/@VMLIMIT_OBJ@/vm-limit.o/ /^RALLOC_OBJ *=/s/@RALLOC_OBJ@/ralloc.o/ -/^UNEXEC_OBJ *=/s/@UNEXEC_OBJ@/unexcoff.o/ /^BUILD_DETAILS *=/s/@BUILD_DETAILS@// /^CANNOT_DUMP *=/s/@CANNOT_DUMP@/no/ /^W32_OBJ *=/s/@W32_OBJ@// @@ -194,9 +193,7 @@ s/ *@WEBP_LIBS@// /^[Aa][Mm]_/s/@AM_V@/$(V)/ /^[Aa][Mm]_/s/@AM_DEFAULT_V@/$(AM_DEFAULT_VERBOSITY)/ /^AUTO_DEPEND *=/s/@AUTO_DEPEND@/yes/ -/^PAXCTL_dumped *=/s/=.*$/=/ -/^PAXCTL_notdumped *=/s/=.*$/=/ -/^DUMPING *=/s/@DUMPING@/unexec/ +/^DUMPING *=/s/@DUMPING@/pdumper/ /^ANDROID_OBJ *=/s/@ANDROID_OBJ@// /^ANDROID_LIBS *=/s/@ANDROID_LIBS@// /^ANDROID_LDFLAGS *=/s/@ANDROID_LDFLAGS@// @@ -205,8 +202,6 @@ s/ *@WEBP_LIBS@// /^SQLITE3_CFLAGS *=/s/@SQLITE3_CFLAGS@// /^LIBSELINUX_CFLAGS *=/s/@LIBSELINUX_CFLAGS@// /^XCONFIGURE *=/s/@XCONFIGURE@// -/^[ \t]*MAKE_PDUMPER_FINGERPRINT = *$/c\ -MAKE_PDUMPER_FINGERPRINT = # While this variable is named abs_top_builddir, the distinction is # only relevant when Emacs is undergoing cross-compilation. /^abs_top_builddir =*/s/@abs_top_builddir@/../ @@ -237,14 +232,8 @@ lisp.mk: $(lispsource)/loadup.el\ /^ *ln /s/ln /cp / /^ fi/d /ifeq (\$(HAVE_NATIVE_COMP):\$(NATIVE_DISABLED),yes:)/,/endif/d -/^ *\$(RUN_TEMACS) /i\ - stubedit temacs.exe minstack=1024k -/^ *LC_ALL=C \$(RUN_TEMACS)/i\ - stubedit temacs.exe minstack=1024k /^ *LC_ALL=C.*\$(RUN_TEMACS)/s/LC_ALL=C/set &;/ -/-batch .* -l loadup/a\ - stubify emacs\ - stubedit emacs.exe minstack=3072k +/^ ANCIENT=yes \$(MAKE) -C ..\/lisp compile-first EMACS="\$(bootstrap_exe)"/d s/ @true *$/ @rem/ s/^ [^ ]*move-if-change / update / /^ [^ ]*echo[ ][ ]*timestamp/s/echo /djecho / @@ -271,6 +260,8 @@ s/echo.*buildobj.lst/dj&/ /^ *\$(AM_V_GEN)for /,/mv \$@.tmp \$@/c\ djecho "$(ALLOBJS)" | sed -e 's/^ */"/' -e 's/ *$$/"/' -e 's/ */", "/g' >>$@ } +/^ .*\$(MAKE_PDUMPER_FINGERPRINT) \$@\.tmp/s/\.tmp// +/^ rm -f \$@ && cp -f temacs\$(EXEEXT) \$@/s/rm -f \$@ && // # Remove or replace dependencies we cannot have /^\.PRECIOUS: /s!\.\./config.status !! /^\.\.\/config.status: /,/^ /d @@ -293,3 +284,4 @@ s| -I\. -I\$(srcdir)| -I.| /\$(CC) -o \$@.tmp/s/\$@.tmp/\$@/ /mv \$@.tmp \$@/d /^top_builddir =*/s/@top_builddir@/../ +s/\.pdmp/\.dmp/ diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp index b6e4bda89e2..ff6eca0f625 100644 --- a/msdos/sed2v2.inp +++ b/msdos/sed2v2.inp @@ -37,7 +37,6 @@ /^#undef HAVE_STRUCT_UTIMBUF *$/s/^.*$/#define HAVE_STRUCT_UTIMBUF 1/ /^#undef LOCALTIME_CACHE *$/s/^.*$/#define LOCALTIME_CACHE 1/ /^#undef HAVE_TZSET *$/s/^.*$/#define HAVE_TZSET 1/ -/^#undef HAVE_UNEXEC *$/s/^.*$/#define HAVE_UNEXEC 1/ /^#undef HAVE_RINT *$/s/^.*$/#define HAVE_RINT 1/ /^#undef HAVE_C99_STRTOLD *$/s/^.*$/#define HAVE_C99_STRTOLD 1/ /^#undef HAVE_DIFFTIME *$/s/^.*$/#define HAVE_DIFFTIME 1/ @@ -138,6 +137,7 @@ s/^#undef HAVE_DECL_PUTCHAR_UNLOCKED *$/#define HAVE_DECL_PUTCHAR_UNLOCKED 0/ s/^#undef HAVE_DECL_PUTC_UNLOCKED *$/#define HAVE_DECL_PUTC_UNLOCKED 0/ s/^#undef HAVE_DECL_STRTOLL *$/#define HAVE_DECL_STRTOLL 1/ s/^#undef HAVE_DECL_STRTOIMAX *$/#define HAVE_DECL_STRTOIMAX 1/ +s/^#undef HAVE_PDUMPER *$/#define HAVE_PDUMPER 1/ s/^#undef HAVE_STRTOLL *$/#define HAVE_STRTOLL 1/ s/^#undef HAVE_STRTOULL *$/#define HAVE_STRTOULL 1/ /^#undef HAVE_STRUCT_DIRENT_D_TYPE *$/c\ diff --git a/msdos/sed6.inp b/msdos/sed6.inp index adc805a4240..687ece9d8ee 100644 --- a/msdos/sed6.inp +++ b/msdos/sed6.inp @@ -17,6 +17,7 @@ # # ---------------------------------------------------------------------- /^srcdir *=/s/@[^@\n]*@/./ +/^top_srcdir *=/s/@[^@\n]*@/..\/../ /^VPATH *=/s/@[^@\n]*@/./ /^MAKEINFO *=/s/@[^@\n]*@/makeinfo/ /^AM_DEFAULT_VERBOSITY *=/s/@AM_DEFAULT_VERBOSITY@/1/ diff --git a/msdos/sedlibmk.inp b/msdos/sedlibmk.inp index aca8857bc44..7af9a9ae7db 100644 --- a/msdos/sedlibmk.inp +++ b/msdos/sedlibmk.inp @@ -208,6 +208,7 @@ s/@PACKAGE@/emacs/ # # Edit the HAVE_foo variables /^HAVE_ATOLL *=/s/@HAVE_ATOLL@/0/ +/^HAVE_BLKCNT_T *=/s/@HAVE_BLKCNT_T@/1/ /^HAVE_CHOWN *=/s/@HAVE_CHOWN@/1/ /^HAVE_CLOSEDIR *=/s/@HAVE_CLOSEDIR@/1/ /^HAVE_DECL_GETPAGESIZE *=/s/@HAVE_DECL_GETPAGESIZE@/1/ diff --git a/src/emacs.c b/src/emacs.c index f0281044c9e..42074c56271 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -885,7 +885,11 @@ load_pdump (int argc, char **argv, char *dump_file) return argv[0]; #else +#ifdef MSDOS + const char *const suffix = ".dmp"; +#else /* !MSDOS */ const char *const suffix = ".pdmp"; +#endif /* !MSDOS */ int result; char *emacs_executable = argv[0]; ptrdiff_t hexbuf_size; diff --git a/src/lisp.h b/src/lisp.h index ff999c7731d..88a3921ca79 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3399,9 +3399,10 @@ CHECK_SUBR (Lisp_Object x) for more efficient dump loading. */ #ifdef DARWIN_OS # define SUBR_SECTION_ATTRIBUTE ATTRIBUTE_SECTION ("__DATA,subrs") -#else +#else /* !DARWIN_OS */ # define SUBR_SECTION_ATTRIBUTE ATTRIBUTE_SECTION (".subrs") -#endif +#endif /* !DARWIN_OS */ + /* Define a built-in function for calling from Lisp. `lname' should be the name to give the function in Lisp, diff --git a/src/pdumper.c b/src/pdumper.c index dee13fb9a81..0cb5ddda644 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -4243,8 +4243,24 @@ types. */) ctx->old_process_environment = Vprocess_environment; Vprocess_environment = Qnil; - ctx->fd = emacs_open (SSDATA (filename), - O_RDWR | O_TRUNC | O_CREAT, 0666); + { + USE_SAFE_ALLOCA; + + char *filename_1; + SAFE_ALLOCA_STRING (filename_1, filename); +#ifdef MSDOS + /* Rewrite references to .pdmp to refer to .dmp files on DOS. */ + size_t len = strlen (filename_1); + if (len >= 5 + && !strcmp (filename_1 + len - 5, ".pdmp")) + { + strcpy (filename_1 + len - 5, ".dmp"); + filename = DECODE_FILE (build_unibyte_string (filename_1)); + } +#endif /* !MSDOS */ + ctx->fd = emacs_open (filename_1, O_RDWR | O_TRUNC | O_CREAT, 0666); + SAFE_FREE (); + } if (ctx->fd < 0) report_file_error ("Opening dump output", filename); static_assert (sizeof (ctx->header.magic) == sizeof (dump_magic)); -- 2.39.5