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".
This commit is contained in:
Po Lu 2025-02-20 14:04:59 +08:00
parent 89f9377139
commit c22957c4bf
12 changed files with 142 additions and 32 deletions

View file

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

View file

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

View file

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

95
msdos/emacs.djl Normal file
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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