Reply-To: mule@etl.go.jp Errors-To: handa@etl.go.jp Sender: handa@etl.go.jp X-Seqno: 1469 Return-Path: Date: Thu, 11 Jan 1996 09:11:27 +0900 From: NIIBE Yutaka To: mule@etl.go.jp Subject: mule on Linux/ELF In-Reply-To: <9601102246.AA06291@milanese.MIT.EDU> References: <9601102246.AA06291@milanese.MIT.EDU> Bob Hyers writes: > Does anyone have a version of mule that will compile on linux with ELF > (like Slackware 3.0)? I don't know about Slackware 3.0, so I'm speaking about my environment which is ELF based and includes kernel 1.3.56, gcc-2.7.2, and libc-5.2.18. I append my Notes file of mule-2.3. It includes patches for mule-2.3, and the procedure to build mule and file listing of mule-2.3. There are problems about libc for mule-2.3, (1) New libc (version 5) doesn't include termcap. (I'm using ncurses instead.) (2) Implementation of STDIO of new libc has changed. (3) START_FILES has changed. Besides, there is ELF specific problem which relates the representation of Lisp objects in Mule. Emacs-19.29 and later solves the problem, but here I use my work around for mule-2.3. And well..., I enabled SIGIO as newer kernel has the feature. Hope this helps, -- NIIBE Yutaka Mitsubishi Research Institute, Inc. After you applied the attached patch, run configure script as below: ./configure [ _SOME_YOUR_OWN_ARGS_ ] i486-linux ---patch------------------------------------------------------------------- diff -aruN mule/src/elf32_i386.custom mule.new/src/elf32_i386.custom --- mule/src/elf32_i386.custom Thu Jan 1 09:00:00 1970 +++ mule.new/src/elf32_i386.custom Fri Oct 3 10:26:42 1997 @@ -0,0 +1,107 @@ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", + "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/i486-linux/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x00400000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x9090 + .plt : { *(.plt) } + .text : + { + *(.text) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0x9090 + _etext = .; + PROVIDE (etext = .); + .fini : { *(.fini) } =0x9090 + .rodata : { *(.rodata) } + .rodata1 : { *(.rodata1) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. It would + be more correct to do this: + . = ALIGN(0x1000) + + ((ALIGN(8) + 0x1000 - ALIGN(0x1000)) + & (0x1000 - 1); + The current expression does not correctly handle the case of a + text segment ending precisely at the end of a page; it causes the + data segment to skip a page. The above expression does not have + this problem, but it will currently (2/95) cause BFD to allocate + a single segment, combining both text and data, for this case. + This will prevent the text segment from being shared among + multiple executions of the program; I think that is more + important than losing a page of the virtual address space (note + that no actual memory is lost; the page which is skipped can not + be referenced). */ + . = ALIGN(0x1000) + ((ALIGN(8) + 0x1000 - ALIGN(0x1000)) & (0x1000 - 1)); + .data : + { + *(.data) + CONSTRUCTORS + } + .data1 : { *(.data1) } + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the .debug DWARF section are relative to the beginning of the + section so we begin .debug at 0. It's not clear yet what needs to happen + for the others. */ + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /* These must appear regardless of . */ +} diff -aruN mule/src/keyboard.c mule.new/src/keyboard.c --- mule/src/keyboard.c Fri Feb 3 10:21:28 1995 +++ mule.new/src/keyboard.c Fri Oct 3 10:25:46 1997 @@ -650,7 +650,7 @@ /* Display the current echo string, and begin echoing if not already doing so. */ - +static void echo () { if (!immediate_echo) diff -aruN mule/src/s/linux.h mule.new/src/s/linux.h --- mule/src/s/linux.h Fri Nov 4 20:11:18 1994 +++ mule.new/src/s/linux.h Fri Oct 3 10:38:22 1997 @@ -58,7 +58,7 @@ is done, you may, at your discretion, uncomment the line below. */ -/* #define INTERRUPT_INPUT */ +#define INTERRUPT_INPUT /* Letter to use in finding device name of first pty, if system supports pty's. 'p' means it is /dev/ptyp0 */ @@ -72,6 +72,8 @@ #define HAVE_TERMIOS +#define TERMINFO + /* * Define HAVE_TIMEVAL if the system supports the BSD style clock values. * Look in for a timeval structure. @@ -157,7 +159,7 @@ #ifdef emacs #include /* Get the definition of _IO_STDIO_H. */ -#ifdef _IO_STDIO_H +#if 1 /* def _IO_STDIO_H */ /* new C libio names */ #define GNU_LIBRARY_PENDING_OUTPUT_COUNT(FILE) \ ((FILE)->_IO_write_ptr - (FILE)->_IO_write_base) @@ -169,13 +171,7 @@ #endif /* emacs */ /* Linux has crt0.o in a non-standard place */ -#define START_FILES pre-crt0.o /usr/lib/crt0.o - -/* As of version 1.1.51, Linux does not actually implement SIGIO. */ -/* Here we assume that signal.h is already included. */ -#ifdef emacs -#undef SIGIO -#endif +#define START_FILES pre-crt0.o /usr/lib/crt1.o /usr/lib/crti.o /* This is needed for sysdep.c */ @@ -201,8 +197,10 @@ /* Best not to include -lg, unless it is last on the command line */ #define LIBS_DEBUG -#define LIBS_TERMCAP -ltermcap -lcurses /* save some space with shared libs*/ -#define LIB_STANDARD -lc /* avoid -lPW */ +#define LIBS_TERMCAP -lncurses /* save some space with shared libs*/ +#undef LIB_GCC +#define LIB_GCC +#define LIB_STANDARD -lgcc -lc -lgcc /usr/lib/crtn.o /* avoid -lPW */ /* Don't use -g in test compiles in configure. This is so we will use the same shared libs for that linking @@ -234,17 +232,20 @@ #ifdef LINUX_QMAGIC #define HAVE_TEXT_START -#define UNEXEC unexsunos4.o #define N_PAGSIZ(x) PAGE_SIZE #else /* not LINUX_QMAGIC */ +#define UNEXEC unexelf.o +#define UNEXEC_USE_MAP_PRIVATE #define A_TEXT_OFFSET(hdr) (N_MAGIC(hdr) == QMAGIC ? sizeof (struct exec) : 0) #define A_TEXT_SEEK(hdr) (N_TXTOFF(hdr) + A_TEXT_OFFSET(hdr)) #define ADJUST_EXEC_HEADER \ unexec_text_start = N_TXTADDR(ohdr) + A_TEXT_OFFSET(ohdr) #endif /* not LINUX_QMAGIC */ + +#define LD_SWITCH_SYSTEM -T elf32_i386.custom #if 0 /* In 19.23 and 19.24, configure sometimes fails to define these. diff -aruN mule/src/unexelf.c mule.new/src/unexelf.c --- mule/src/unexelf.c Fri Oct 21 13:21:00 1994 +++ mule.new/src/unexelf.c Fri Oct 3 10:25:47 1997 @@ -423,6 +423,7 @@ #ifndef emacs #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1) #else +#include "config.h" extern void fatal (char *, ...); #endif @@ -582,8 +583,13 @@ if (ftruncate (new_file, new_file_size)) fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno); +#ifdef UNEXEC_USE_MAP_PRIVATE + new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, + new_file, 0); +#else new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED, new_file, 0); +#endif if (new_base == (caddr_t) -1) fatal ("Can't mmap (%s): errno %d\n", new_name, errno); @@ -718,11 +724,19 @@ NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign; NEW_SECTION_H (nn).sh_size = 0; } - /* Any section that was original placed AFTER the bss section should now - be off by NEW_DATA2_SIZE. */ - else if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset) - NEW_SECTION_H (nn).sh_offset += new_data2_size; - + else + { + /* Any section that was original placed AFTER the bss + section should now be off by NEW_DATA2_SIZE. */ + if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset) + NEW_SECTION_H (nn).sh_offset += new_data2_size; + /* Any section that was originally placed after the section + header table should now be off by the size of one section + header table entry. */ + if (NEW_SECTION_H (nn).sh_offset > new_file_h->e_shoff) + NEW_SECTION_H (nn).sh_offset += new_file_h->e_shentsize; + } + /* If any section hdr refers to the section after the new .data section, make it refer to next one because we have inserted a new section in between. */ @@ -743,10 +757,6 @@ ".data" in the strings table) get copied from the current process instead of the old file. */ if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") -#ifdef _nec_ews_svr4 /* hir, 1994.6.13 */ - || !strcmp ((old_section_names + NEW_SECTION_H(n).sh_name), - ".sdata") -#endif || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), ".data1")) src = (caddr_t) OLD_SECTION_H (n).sh_addr; @@ -786,7 +796,8 @@ && NEW_SECTION_H (n).sh_type != SHT_SYMTAB) continue; - symnames = NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset + new_base; + symnames = ((byte *) new_base + + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset); symp = (Elf32_Sym *) (NEW_SECTION_H (n).sh_offset + new_base); symendp = (Elf32_Sym *) ((byte *)symp + NEW_SECTION_H (n).sh_size); @@ -795,6 +806,14 @@ || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0) memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr)); } + +#ifdef UNEXEC_USE_MAP_PRIVATE + if (lseek (new_file, 0, SEEK_SET) == -1) + fatal ("Can't rewind (%s): errno %d\n", new_name, errno); + + if (write (new_file, new_base, new_file_size) != new_file_size) + fatal ("Can't write (%s): errno %d\n", new_name, errno); +#endif /* Close the files and make the new file executable. */