home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.emacs
- Path: sparky!uunet!usc!rpi!ghost.dsi.unimi.it!itnsg1.cineca.it!lele
- From: lele@itnsg1.cineca.it (Lele Gaifax)
- Subject: Re: Building Emacs on a NeXT
- Message-ID: <1992Aug13.092902.5260@itnsg1.cineca.it>
- Organization: Laboratorio di Fisica Computazionale, INFM. Trento Italia
- References: <1992Aug12.192846.13997@ctr.columbia.edu>
- Date: Thu, 13 Aug 1992 09:29:02 GMT
- Lines: 678
-
- Here is the patches I used to compile 18.58 on my NeXTstation with NeXTstep 2.2.
- I extracted them from an emacs-18.57.tar.Z available on several NeXT archives.
- Apply it to a fresh 18.58 distribution, modify src/config.h to use s-mach.h and
- m-NeXT.h, then do a make... That's it.
- I did not write a single bit of this code, I just produced it diff-ing the
- 18.57 sources against 18.58....
- bye, lele.
-
- --- src/emacs.c.orig Sat Jun 15 04:52:00 1991
- +++ src/emacs.c Sat Jun 15 04:56:55 1991
- @@ -178,6 +178,9 @@
- #endif /* LINK_CRTL_SHARE */
- #endif /* VMS */
-
- +#ifdef NeXT
- +int malloc_cookie;
- +#endif /* NeXT */
- /* ARGSUSED */
- main (argc, argv, envp)
- int argc;
- @@ -187,6 +190,13 @@
- int skip_args = 0;
- extern int errno;
- extern void malloc_warning ();
- +
- +#ifdef NeXT
- + /* this helps out unexNeXT.c */
- + if (initialized)
- + if (malloc_jumpstart(malloc_cookie) != 0)
- + printf("malloc jumpstart failed!\n");
- +#endif /* NeXT */
-
- /* Map in shared memory, if we are using that. */
- #ifdef HAVE_SHM
- --- src/fns.c.orig Sat Jun 15 04:52:03 1991
- +++ src/fns.c Sat Jun 15 04:53:01 1991
- @@ -1204,8 +1204,13 @@
- nl[0].n_un.n_name = LDAV_SYMBOL;
- nl[1].n_un.n_name = 0;
- #else /* not convex */
- +#ifdef NEXT_KERNEL_FILE
- + nl[0].n_un.n_name = LDAV_SYMBOL;
- + nl[1].n_un.n_name = 0;
- +#else
- nl[0].n_name = LDAV_SYMBOL;
- nl[1].n_name = 0;
- +#endif /* not NEXT_KERNEL_FILE */
- #endif /* not convex */
- #endif /* NLIST_STRUCT */
-
- @@ -1217,7 +1222,11 @@
- nl[0].n_value &= 0x7fffffff;
- }
- #else
- +#ifdef NEXT_KERNEL_FILE
- + nlist (NEXT_KERNEL_FILE, nl);
- +#else
- nlist (KERNEL_FILE, nl);
- +#endif
- #endif /* IRIS */
-
- #ifdef FIXUP_KERNEL_SYMBOL_ADDR
- --- src/sysdep.c.orig Sat Jun 15 04:52:04 1991
- +++ src/sysdep.c Sat Jun 15 04:53:03 1991
- @@ -1472,8 +1472,12 @@
- extern csrt();
- return ((char *) csrt);
- #else /* not GOULD */
- +#ifdef NeXT
- + return ((char *)0); /* wrong: but nobody uses it anyway */
- +#else
- extern int _start ();
- return ((char *) _start);
- +#endif /* NeXT */
- #endif /* GOULD */
- #endif /* TEXT_START */
- }
- @@ -1531,7 +1535,13 @@
- #ifdef TEXT_END
- return ((char *) TEXT_END);
- #else
- +#ifdef __NeXT__
- + static int etext;
- +
- + etext = get_etext();
- +#else
- extern int etext;
- +#endif
- return ((char *) &etext);
- #endif
- }
- @@ -1547,7 +1557,13 @@
- #ifdef DATA_END
- return ((char *) DATA_END);
- #else
- +#ifdef __NeXT__
- + static int edata;
- +
- + edata = get_edata();
- +#else
- extern int edata;
- +#endif
- return ((char *) &edata);
- #endif
- }
- --- src/x11term.c.orig Sat Jun 15 04:52:02 1991
- +++ src/x11term.c Sat Jun 15 04:53:05 1991
- @@ -273,7 +273,9 @@
-
- static void x_init_1 ();
-
- +#ifndef rindex
- char *rindex();
- +#endif /* rindex */
-
- /* HLmode -- Changes the GX function for output strings. Could be used to
- * change font. Check an XText library function call.
- --- /dev/null Wed Jul 15 18:14:58 1992
- +++ src/s-mach.h Sat Jun 15 04:58:01 1991
- @@ -0,0 +1,28 @@
- +/* Definitions file for GNU Emacs running on bsd 4.3
- + Copyright (C) 1985, 1986 Free Software Foundation, Inc.
- +
- +This file is part of GNU Emacs.
- +
- +GNU Emacs is distributed in the hope that it will be useful,
- +but WITHOUT ANY WARRANTY. No author or distributor
- +accepts responsibility to anyone for the consequences of using it
- +or for whether it serves any particular purpose or works at all,
- +unless he says so in writing. Refer to the GNU Emacs General Public
- +License for full details.
- +
- +Everyone is granted permission to copy, modify and redistribute
- +GNU Emacs, but only under the conditions described in the
- +GNU Emacs General Public License. A copy of this license is
- +supposed to have been given to you along with GNU Emacs so you
- +can know your rights and responsibilities. It should be in a
- +file named COPYING. Among other things, the copyright notice
- +and this notice must be preserved on all copies. */
- +
- +
- +#include "s-bsd4-3.h"
- +#define NEXT_KERNEL_FILE "/mach"
- +/* #define NEXT_KERNEL_FILE "/vmunix" */
- +#undef KERNEL_FILE
- +
- +#define LD_SWITCH_SYSTEM -X -noseglinkedit
- +
- --- /dev/null Wed Jul 15 18:14:58 1992
- +++ src/m-NeXT.h Sat Jun 15 04:52:36 1991
- @@ -0,0 +1,98 @@
- +/* Configuration file for the NeXT machine. */
- +/* Copyright (C) 1985, 1986 Free Software Foundation, Inc.
- +
- +This file is part of GNU Emacs.
- +
- +GNU Emacs is distributed in the hope that it will be useful,
- +but WITHOUT ANY WARRANTY. No author or distributor
- +accepts responsibility to anyone for the consequences of using it
- +or for whether it serves any particular purpose or works at all,
- +unless he says so in writing. Refer to the GNU Emacs General Public
- +License for full details.
- +
- +Everyone is granted permission to copy, modify and redistribute
- +GNU Emacs, but only under the conditions described in the
- +GNU Emacs General Public License. A copy of this license is
- +supposed to have been given to you along with GNU Emacs so you
- +can know your rights and responsibilities. It should be in a
- +file named COPYING. Among other things, the copyright notice
- +and this notice must be preserved on all copies. */
- +
- +
- +
- +
- +
- +
- +
- +/* The following three symbols give information on
- + the size of various data types. */
- +
- +#define SHORTBITS 16 /* Number of bits in a short */
- +
- +#define INTBITS 32 /* Number of bits in an int */
- +
- +#define LONGBITS 32 /* Number of bits in a long */
- +
- +/* 68000 has lowest-numbered byte as most significant */
- +
- +#define BIG_ENDIAN
- +
- +/* Define how to take a char and sign-extend into an int.
- + On machines where char is signed, this is a no-op. */
- +
- +#define SIGN_EXTEND_CHAR(c) (c)
- +
- +/* Say this machine is a 68000 */
- +
- +#ifndef m68000
- +#define m68000
- +#endif
- +
- +/* Use type int rather than a union, to represent Lisp_Object */
- +
- +#define NO_UNION_TYPE
- +
- +/* XINT must explicitly sign-extend */
- +
- +#define EXPLICIT_SIGN_EXTEND
- +
- +#define LIB_STANDARD -lsys_s
- +
- +/* Data type of load average, as read out of kmem. */
- +
- +#define LOAD_AVE_TYPE long
- +
- +/* Convert that into an integer that is 100 for a load average of 1.0 */
- +
- +#define environ _environ
- +
- +#define NO_REMAP
- +#define UNEXEC unexNeXT.o
- +
- +#ifndef FSCALE
- +#define FSCALE 256
- +#endif
- +#define LOAD_AVE_CVT(x) (int) (((double) (x)) * 100.0 / FSCALE)
- +
- +/* Say that the text segment of a.out includes the header;
- + the header actually occupies the first few bytes of the text segment
- + and is counted in hdr.a_text. */
- +
- +#define A_TEXT_OFFSET(HDR) sizeof (HDR)
- +
- +/* #define _setjmp setjmp */
- +/* #define _longjmp longjmp */
- +
- +/* Use dk.h, not dkstat.h, in loadst.c. */
- +
- +#define DK_HEADER_FILE
- +/* Mask for address bits within a memory segment */
- +
- +#define SEGSIZ 0x20000
- +#define SEGMENT_MASK (SEGSIZ - 1)
- +
- +#define HAVE_ALLOCA
- +
- +#define SYSTEM_MALLOC
- +
- +#define HAVE_UNIX_DOMAIN
- --- /dev/null Wed Jul 15 18:14:58 1992
- +++ src/unexNeXT.c Sat Jun 15 04:52:35 1991
- @@ -0,0 +1,422 @@
- +/*
- + * unexec for the NeXT Mach environment.
- + *
- + * Bradley Taylor (btaylor@NeXT.COM)
- + * February 28, 1990
- + */
- +#ifdef NeXT
- +
- +#undef __STRICT_BSD__
- +
- +#include <stdio.h>
- +#include <stdlib.h>
- +#include <stdarg.h>
- +#include <mach.h>
- +#include <sys/loader.h>
- +#include <sys/file.h>
- +#include <sys/stat.h>
- +#include <libc.h>
- +
- +
- +extern struct section *getsectbyname(char *, char *);
- +
- +/*
- + * Kludge: we don't expect any program data beyond VM_HIGHDATA
- + * What is really needed is a way to find out from malloc() which
- + * pages it vm_allocated and write only those out into the data segment.
- + *
- + * This kludge may break when we stop using fixed virtual address
- + * shared libraries. Actually, emacs will probably continue working, but be
- + * much larger on disk than it needs to be (because non-malloced data will
- + * be in the file).
- + */
- +static const unsigned VM_HIGHDATA = 0x2000000;
- +
- +typedef struct region_t {
- + vm_address_t address;
- + vm_size_t size;
- + vm_prot_t protection;
- + vm_prot_t max_protection;
- + vm_inherit_t inheritance;
- + boolean_t shared;
- + port_t object_name;
- + vm_offset_t offset;
- +} region_t;
- +
- +
- +static void
- +grow(
- + struct load_command ***the_commands,
- + unsigned *the_commands_len
- + )
- +{
- + if (*the_commands == NULL) {
- + *the_commands_len = 1;
- + *the_commands = malloc(sizeof(*the_commands));
- + } else {
- + (*the_commands_len)++;
- + *the_commands = realloc(*the_commands,
- + (*the_commands_len *
- + sizeof(**the_commands)));
- + }
- +}
- +
- +
- +static void
- +save_command(
- + struct load_command *command,
- + struct load_command ***the_commands,
- + unsigned *the_commands_len
- + )
- +{
- + struct load_command **tmp;
- +
- + grow(the_commands, the_commands_len);
- + tmp = &(*the_commands)[*the_commands_len - 1];
- + *tmp = malloc(command->cmdsize);
- + bcopy(command, *tmp, command->cmdsize);
- +}
- +
- +static void
- +fatal_unexec(char *format, ...)
- +{
- + va_list ap;
- +
- + va_start(ap, format);
- + fprintf(stderr, "unexec: ");
- + vfprintf(stderr, format, ap);
- + fprintf(stderr, "\n");
- + va_end(ap);
- +}
- +
- +static int
- +read_macho(
- + int fd,
- + struct mach_header *the_header,
- + struct load_command ***the_commands,
- + unsigned *the_commands_len
- + )
- +{
- + struct load_command command;
- + struct load_command *buf;
- + int i;
- + int size;
- +
- + if (read(fd, the_header, sizeof(*the_header)) != sizeof(*the_header)) {
- + fatal_unexec("cannot read macho header");
- + return (0);
- + }
- + for (i = 0; i < the_header->ncmds; i++) {
- + if (read(fd, &command, sizeof(struct load_command)) !=
- + sizeof(struct load_command)) {
- + fatal_unexec("cannot read macho load command header");
- + return (0);
- + }
- + size = command.cmdsize - sizeof(struct load_command);
- + if (size < 0) {
- + fatal_unexec("bogus load command size");
- + return (0);
- + }
- + buf = malloc(command.cmdsize);
- + buf->cmd = command.cmd;
- + buf->cmdsize = command.cmdsize;
- + if (read(fd, ((char *)buf +
- + sizeof(struct load_command)),
- + size) != size) {
- + fatal_unexec("cannot read load command data");
- + return (0);
- + }
- + save_command(buf, the_commands, the_commands_len);
- + }
- + return (1);
- +}
- +
- +static int
- +filldatagap(
- + vm_address_t start_address,
- + vm_size_t *size,
- + vm_address_t end_address
- + )
- +{
- + vm_address_t address;
- + vm_size_t gapsize;
- +
- + address = (start_address + *size);
- + gapsize = end_address - address;
- + *size += gapsize;
- + if (vm_allocate(task_self(), &address, gapsize,
- + FALSE) != KERN_SUCCESS) {
- + fatal_unexec("cannot vm_allocate");
- + return (0);
- + }
- + return (1);
- +}
- +
- +static int
- +get_data_region(
- + vm_address_t *address,
- + vm_size_t *size
- + )
- +{
- + region_t region;
- + kern_return_t ret;
- + struct section *sect;
- +
- + sect = getsectbyname(SEG_DATA, SECT_DATA);
- + region.address = 0;
- + *address = 0;
- + for (;;) {
- + ret = vm_region(task_self(),
- + ®ion.address,
- + ®ion.size,
- + ®ion.protection,
- + ®ion.max_protection,
- + ®ion.inheritance,
- + ®ion.shared,
- + ®ion.object_name,
- + ®ion.offset);
- + if (ret != KERN_SUCCESS || region.address >= VM_HIGHDATA) {
- + break;
- + }
- + if (*address != 0) {
- + if (region.address > *address + *size) {
- + if (!filldatagap(*address, size,
- + region.address)) {
- + return (0);
- + }
- + }
- + *size += region.size;
- + } else {
- + if (region.address == sect->addr) {
- + *address = region.address;
- + *size = region.size;
- + }
- + }
- + region.address += region.size;
- + }
- + return (1);
- +}
- +
- +static char *
- +my_malloc(
- + vm_size_t size
- + )
- +{
- + vm_address_t address;
- +
- + if (vm_allocate(task_self(), &address, size, TRUE) != KERN_SUCCESS) {
- + return (NULL);
- + }
- + return ((char *)address);
- +}
- +
- +static void
- +my_free(
- + char *buf,
- + vm_size_t size
- + )
- +{
- + vm_deallocate(task_self(), (vm_address_t)buf, size);
- +}
- +
- +static int
- +unexec_doit(
- + int infd,
- + int outfd
- + )
- +{
- + int i;
- + struct load_command **the_commands = NULL;
- + unsigned the_commands_len;
- + struct mach_header the_header;
- + int fgrowth;
- + int fdatastart;
- + int fdatasize;
- + int size;
- + struct stat st;
- + char *buf;
- + vm_address_t data_address;
- + vm_size_t data_size;
- +
- + struct segment_command *segment;
- +
- + if (!read_macho(infd, &the_header, &the_commands, &the_commands_len)) {
- + return (0);
- + }
- +
- +
- + {
- + extern int malloc_cookie;
- + malloc_cookie = malloc_freezedry();
- + }
- + if (!get_data_region(&data_address, &data_size)) {
- + return (0);
- + }
- +
- +
- + /*
- + * DO NOT USE MALLOC IN THIS SECTION
- + */
- + {
- + /*
- + * Fix offsets
- + */
- + for (i = 0; i < the_commands_len; i++) {
- + switch (the_commands[i]->cmd) {
- + case LC_SEGMENT:
- + segment = ((struct segment_command *)
- + the_commands[i]);
- + if (strcmp(segment->segname, SEG_DATA) == 0) {
- + fdatastart = segment->fileoff;
- + fdatasize = segment->filesize;
- + fgrowth = (data_size -
- + segment->filesize);
- + segment->vmsize = data_size;
- + segment->filesize = data_size;
- + }
- + break;
- + case LC_SYMTAB:
- + ((struct symtab_command *)
- + the_commands[i])->symoff += fgrowth;
- + ((struct symtab_command *)
- + the_commands[i])->stroff += fgrowth;
- + break;
- + case LC_SYMSEG:
- + ((struct symseg_command *)
- + the_commands[i])->offset += fgrowth;
- + break;
- + default:
- + break;
- + }
- + }
- +
- + /*
- + * Write header
- + */
- + if (write(outfd, &the_header,
- + sizeof(the_header)) != sizeof(the_header)) {
- + fatal_unexec("cannot write output file");
- + return (0);
- + }
- +
- + /*
- + * Write commands
- + */
- + for (i = 0; i < the_commands_len; i++) {
- + if (write(outfd, the_commands[i],
- + the_commands[i]->cmdsize) !=
- + the_commands[i]->cmdsize) {
- + fatal_unexec("cannot write output file");
- + return (0);
- + }
- + }
- +
- + /*
- + * Write original text
- + */
- + if (lseek(infd, the_header.sizeofcmds + sizeof(the_header),
- + L_SET) < 0) {
- + fatal_unexec("cannot seek input file");
- + return (0);
- + }
- + size = fdatastart - (sizeof(the_header) +
- + the_header.sizeofcmds);
- + buf = my_malloc(size);
- + if (read(infd, buf, size) != size) {
- + my_free(buf, size);
- + fatal_unexec("cannot read input file");
- + }
- + if (write(outfd, buf, size) != size) {
- + my_free(buf, size);
- + fatal_unexec("cannot write output file");
- + return (0);
- + }
- + my_free(buf, size);
- +
- +
- + /*
- + * Write new data
- + */
- + if (write(outfd, (char *)data_address,
- + data_size) != data_size) {
- + fatal_unexec("cannot write output file");
- + return (0);
- + }
- +
- + }
- +
- + /*
- + * OKAY TO USE MALLOC NOW
- + */
- +
- + /*
- + * Write rest of file
- + */
- + fstat(infd, &st);
- + if (lseek(infd, fdatasize, L_INCR) < 0) {
- + fatal_unexec("cannot seek input file");
- + return (0);
- + }
- + size = st.st_size - lseek(infd, 0, L_INCR);
- +
- + buf = malloc(size);
- + if (read(infd, buf, size) != size) {
- + free(buf);
- + fatal_unexec("cannot read input file");
- + return (0);
- + }
- + if (write(outfd, buf, size) != size) {
- + free(buf);
- + fatal_unexec("cannot write output file");
- + return (0);
- + }
- + free(buf);
- + return (1);
- +}
- +
- +void
- +unexec(
- + char *outfile,
- + char *infile
- + )
- +{
- + int infd;
- + int outfd;
- + char tmpbuf[L_tmpnam];
- + char *tmpfile;
- +
- + infd = open(infile, O_RDONLY, 0);
- + if (infd < 0) {
- + fatal_unexec("cannot open input file `%s'", infile);
- + exit(1);
- + }
- +
- + tmpnam(tmpbuf);
- + tmpfile = rindex(tmpbuf, '/');
- + if (tmpfile == NULL) {
- + tmpfile = tmpbuf;
- + } else {
- + tmpfile++;
- + }
- + outfd = open(tmpfile, O_WRONLY|O_TRUNC|O_CREAT, 0755);
- + if (outfd < 0) {
- + close(infd);
- + fatal_unexec("cannot open tmp file `%s'", tmpfile);
- + exit(1);
- + }
- + if (!unexec_doit(infd, outfd)) {
- + close(infd);
- + close(outfd);
- + unlink(tmpfile);
- + exit(1);
- + }
- + close(infd);
- + close(outfd);
- + if (rename(tmpfile, outfile) < 0) {
- + unlink(tmpfile);
- + fatal_unexec("cannot rename `%s' to `%s'", tmpfile, outfile);
- + exit(1);
- + }
- +}
- +#endif
- +
- --
- Lele Gaifax - lele@itnsg1.cineca.it
- Sicuramente i cattivi hanno scoperto qualche cosa che i buoni ignorano.
- - Woody Allen
-