Index: emacs/Makefile.in =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/Makefile.in,v retrieving revision 1.1.1.7 retrieving revision 1.7 diff -u -r1.1.1.7 -r1.7 --- Makefile.in 2002/09/10 23:31:56 1.1.1.7 +++ Makefile.in 2002/09/11 01:34:01 1.7 @@ -329,7 +329,6 @@ libexecdir=${libexecdir} archlibdir=${archlibdir} \ INSTALL_STRIP=${INSTALL_STRIP}) ${INSTALL_PROGRAM} $(INSTALL_STRIP) src/emacs ${bindir}/emacs-${version} - -chmod 1755 ${bindir}/emacs-${version} rm -f ${bindir}/$(EMACS) -ln ${bindir}/emacs-${version} ${bindir}/$(EMACS) -unset CDPATH; \ @@ -447,7 +446,7 @@ -chmod -R a+r ${datadir}/emacs ${COPYDESTS} ${infodir} thisdir=`/bin/pwd`; \ cd ${srcdir}/etc; \ - for page in emacs etags ctags gfdl ; do \ + for page in emacs etags gfdl ; do \ (cd $${thisdir}; \ ${INSTALL_DATA} ${srcdir}/etc/$${page}.1 ${man1dir}/$${page}${manext}; \ chmod a+r ${man1dir}/$${page}${manext}); \ Index: emacs/lib-src/Makefile.in =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/lib-src/Makefile.in,v retrieving revision 1.1.1.6 retrieving revision 1.4 diff -u -r1.1.1.6 -r1.4 --- Makefile.in 2001/10/31 17:59:51 1.1.1.6 +++ Makefile.in 2001/12/13 02:44:29 1.4 @@ -92,7 +92,7 @@ # Things that a user might actually run, # which should be installed in bindir. -INSTALLABLES = etags ctags emacsclient b2m ebrowse +INSTALLABLES = etags emacsclient b2m ebrowse INSTALLABLE_SCRIPTS = rcs-checkin grep-changelog # Things that Emacs runs internally, or during the build process, Index: emacs/lisp/abbrev.elc =================================================================== RCS file: abbrev.elc diff -N abbrev.elc Binary files /dev/null and /tmp/cvs000907 differ Index: emacs/lisp/abbrevlist.elc =================================================================== RCS file: abbrevlist.elc diff -N abbrevlist.elc Binary files /dev/null and /tmp/cvs000907 differ Index: emacs/lisp/add-log.elc =================================================================== RCS file: add-log.elc diff -N add-log.elc Binary files /dev/null and /tmp/cvs000907 differ Index: emacs/lisp/align.elc =================================================================== RCS file: align.elc diff -N align.elc Binary files /dev/null and /tmp/cvs000907 differ Index: emacs/lisp/site-init.el =================================================================== RCS file: site-init.el diff -N site-init.el --- emacs/lisp/site-init.el Tue Sep 17 14:45:13 2002 +++ /tmp/cvs000907 Tue Sep 17 16:29:04 2002 @@ -0,0 +1,4 @@ +;; gnuserv setup. +(autoload 'gnuserv-start "gnuserv-compat" + "Allow this Emacs process to be a server for client processes." + t) Index: emacs/man/Makefile.in =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/man/Makefile.in,v retrieving revision 1.1.1.7 retrieving revision 1.3 diff -u -r1.1.1.7 -r1.3 --- Makefile.in 2002/09/10 23:34:32 1.1.1.7 +++ Makefile.in 2002/09/11 01:34:03 1.3 @@ -31,7 +31,7 @@ # The makeinfo program is part of the Texinfo distribution. -MAKEINFO = makeinfo +MAKEINFO = echo makeinfo INFO_TARGETS = ../info/emacs ../info/ccmode ../info/cl \ ../info/dired-x ../info/ediff ../info/forms ../info/gnus \ ../info/info ../info/message ../info/mh-e ../info/reftex \ Index: emacs/src/emacs.c =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/src/emacs.c,v retrieving revision 1.1.1.7 retrieving revision 1.10 diff -u -r1.1.1.7 -r1.10 --- emacs.c 2002/09/10 23:34:58 1.1.1.7 +++ emacs.c 2002/09/11 01:34:03 1.10 @@ -779,15 +779,20 @@ } #endif -#ifdef NeXT +#if defined(NeXT) || defined(RHAPSODY) || defined(DARWIN) { extern int malloc_cookie; - /* This helps out unexnext.c. */ + /* This helps out unexnext.c/unexdyld.c. */ if (initialized) - if (malloc_jumpstart (malloc_cookie) != 0) - printf ("malloc jumpstart failed!\n"); + { + if (malloc_jumpstart (malloc_cookie) != 0) + { + fprintf (stderr, "Fatal malloc_jumpstart() error\n"); + exit (1); + } + } } -#endif /* NeXT */ +#endif /* NeXT || RHAPSODY || DARWIN */ #ifdef VMS /* If -map specified, map the data file in */ @@ -1466,7 +1471,7 @@ #ifdef VMS init_vmsfns (); #endif /* VMS */ - init_process (); + init_emacs_process (); #ifdef HAVE_SOUND init_sound (); #endif Index: emacs/src/floatfns.c =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/src/floatfns.c,v retrieving revision 1.1.1.7 retrieving revision 1.4 diff -u -r1.1.1.7 -r1.4 --- floatfns.c 2002/09/10 23:34:59 1.1.1.7 +++ floatfns.c 2002/09/11 01:34:04 1.4 @@ -978,6 +978,9 @@ #endif /* FLOAT_CATCH_SIGILL */ #ifdef HAVE_MATHERR +#ifdef __APPLE_CC__ +__private_extern__ +#endif int matherr (x) struct exception *x; Index: emacs/src/getloadavg.c =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/src/getloadavg.c,v retrieving revision 1.1.1.6 retrieving revision 1.4 diff -u -r1.1.1.6 -r1.4 --- getloadavg.c 2001/10/31 17:58:36 1.1.1.6 +++ getloadavg.c 2001/10/31 19:00:48 1.4 @@ -54,6 +54,8 @@ hpux __MSDOS__ No-op for MSDOS. NeXT + RHAPSODY Mac OS X Server + DARWIN Darwin (Mac OS) sgi sequent Sequent Dynix 3.x.x (BSD) _SEQUENT_ Sequent DYNIX/ptx 1.x.x (SYSV) @@ -401,7 +403,7 @@ # define host_self mach_host_self # endif -# ifdef NeXT +# if defined(NeXT) || defined(RHAPSODY) || defined(DARWIN) # ifdef HAVE_MACH_MACH_H # include # else @@ -449,7 +451,7 @@ /* Avoid static vars inside a function since in HPUX they dump as pure. */ -# ifdef NeXT +# if defined(NeXT) || defined(RHAPSODY) || defined(DARWIN) static processor_set_t default_set; static int getloadavg_initialized; # endif /* NeXT */ @@ -486,6 +488,9 @@ Return the number written (never more than 3, but may be less than NELEM), or -1 if an error occurred. */ +#ifdef __APPLE_CC__ +__private_extern__ +#endif int getloadavg (loadavg, nelem) double loadavg[]; @@ -626,14 +631,10 @@ # endif /* __NetBSD__ */ -# if !defined (LDAV_DONE) && defined (NeXT) +# if !defined (LDAV_DONE) && (defined(NeXT) || defined(RHAPSODY) || defined(DARWIN)) # define LDAV_DONE /* The NeXT code was adapted from iscreen 3.2. */ - host_t host; - struct processor_set_basic_info info; - unsigned info_count; - /* We only know how to get the 1-minute average for this system, so even if the caller asks for more than 1, we only return 1. */ @@ -643,10 +644,19 @@ getloadavg_initialized = 1; } +#ifndef DARWIN +#define processor_set_load_info processor_set_basic_info +#define PROCESSOR_SET_LOAD_INFO PROCESSOR_SET_BASIC_INFO +#define PROCESSOR_SET_LOAD_INFO_COUNT PROCESSOR_SET_BASIC_INFO_COUNT +#endif + if (getloadavg_initialized) { - info_count = PROCESSOR_SET_BASIC_INFO_COUNT; - if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, + struct processor_set_load_info info; + host_t host; + unsigned info_count = PROCESSOR_SET_LOAD_INFO_COUNT; + + if (processor_set_info (default_set, PROCESSOR_SET_LOAD_INFO, &host, (processor_set_info_t) &info, &info_count) != KERN_SUCCESS) getloadavg_initialized = 0; Index: emacs/src/lisp.h =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/src/lisp.h,v retrieving revision 1.1.1.7 retrieving revision 1.4 diff -u -r1.1.1.7 -r1.4 --- lisp.h 2002/09/10 23:35:02 1.1.1.7 +++ lisp.h 2002/09/11 01:34:04 1.4 @@ -2770,7 +2770,7 @@ extern void close_process_descs P_ ((void)); extern void status_notify P_ ((void)); extern int read_process_output P_ ((Lisp_Object, int)); -extern void init_process P_ ((void)); +extern void init_emacs_process P_ ((void)); extern void syms_of_process P_ ((void)); /* defined in callproc.c */ Index: emacs/src/process.c =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/src/process.c,v retrieving revision 1.1.1.7 retrieving revision 1.6 diff -u -r1.1.1.7 -r1.6 --- process.c 2002/09/10 23:35:04 1.1.1.7 +++ process.c 2002/09/11 01:34:04 1.6 @@ -1482,7 +1482,11 @@ current_dir = ENCODE_FILE (current_dir); #ifndef WINDOWSNT +#ifndef PUMA_VFORK_ISSUES_CLEARED_UP + pid = fork (); +#else pid = vfork (); +#endif if (pid == 0) #endif /* not WINDOWSNT */ { @@ -4604,7 +4608,7 @@ } void -init_process () +init_emacs_process () { register int i; @@ -5003,7 +5007,7 @@ } void -init_process () +init_emacs_process () { } Index: emacs/src/regex.c =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/src/regex.c,v retrieving revision 1.1.1.7 retrieving revision 1.4 diff -u -r1.1.1.7 -r1.4 Index: emacs/src/sysdep.c =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/src/sysdep.c,v retrieving revision 1.1.1.5 retrieving revision 1.4 diff -u -r1.1.1.5 -r1.4 --- sysdep.c 2002/09/10 23:35:06 1.1.1.5 +++ sysdep.c 2002/09/11 01:34:04 1.4 @@ -813,7 +813,12 @@ synch_process_alive = 1; #endif /* __DJGPP__ > 1 */ #else +#ifndef PUMA_VFORK_ISSUES_CLEARED_UP + pid = fork (); +#else pid = vfork (); +#endif + if (pid == -1) error ("Can't spawn subshell"); #endif Index: emacs/src/term.c =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/src/term.c,v retrieving revision 1.1.1.6 retrieving revision 1.3 diff -u -r1.1.1.6 -r1.3 Index: emacs/src/termcap.c =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/src/termcap.c,v retrieving revision 1.1.1.6 retrieving revision 1.6 diff -u -r1.1.1.6 -r1.6 --- termcap.c 2001/10/31 17:58:46 1.1.1.6 +++ termcap.c 2002/01/08 02:38:33 1.6 @@ -144,6 +144,9 @@ return NULL; } +#ifdef __APPLE_CC__ +__private_extern__ +#endif int tgetnum (cap) char *cap; @@ -154,6 +157,9 @@ return atoi (ptr); } +#ifdef __APPLE_CC__ +__private_extern__ +#endif int tgetflag (cap) char *cap; @@ -167,6 +173,9 @@ to store the string. That pointer is advanced over the space used. If AREA is null, space is allocated with `malloc'. */ +#ifdef __APPLE_CC__ +__private_extern__ +#endif char * tgetstr (cap, area) char *cap; @@ -311,6 +320,9 @@ #endif /* 0 */ +#ifdef __APPLE_CC__ +__private_extern__ +#endif void tputs (str, nlines, outfun) register char *str; @@ -436,6 +448,9 @@ 0 if the data base is accessible but the type NAME is not defined in it, and some other value otherwise. */ +#ifdef __APPLE_CC__ +__private_extern__ +#endif int tgetent (bp, name) char *bp, *name; Index: emacs/src/tparam.c =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/src/tparam.c,v retrieving revision 1.1.1.6 retrieving revision 1.5 diff -u -r1.1.1.6 -r1.5 --- tparam.c 2001/10/31 17:58:47 1.1.1.6 +++ tparam.c 2002/01/08 02:38:33 1.5 @@ -110,6 +110,9 @@ static char tgoto_buf[50]; +#ifdef __APPLE_CC__ +__private_extern__ +#endif char * tgoto (cm, hpos, vpos) char *cm; Index: emacs/src/unexdyld.c =================================================================== RCS file: unexdyld.c diff -N unexdyld.c --- emacs/src/unexdyld.c Tue Sep 17 14:45:13 2002 +++ /tmp/cvs000907 Tue Sep 17 16:29:09 2002 @@ -0,0 +1,996 @@ +/* Dump Emacs in macho format. + Copyright (C) 1990, 1993 Free Software Foundation, Inc. + Derived from unexnext.c by Bradley Taylor (btaylor@next.com). + +This file is part of GNU Emacs. + +GNU Emacs is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "config.h" +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#ifndef NeXT +#include +#endif +#include +#include +#include + +extern int malloc_freezedry (void); + +int malloc_cookie; + +#define VERBOSE + +#ifdef VERBOSE +#define SHOW_MCOPY_WRITES +#define SHOW_MCOPY_READS +#endif + +typedef struct region_t +{ + struct region_t *next; + vm_address_t address; + vm_size_t size; + vm_prot_t protection; + vm_prot_t max_protection; + + /* And some info about where it was written to disk. */ + unsigned long file_offset; + unsigned long file_size; +} region_t; + +typedef struct section_list_t +{ + struct section_list_t *next; + struct section section; +} section_list_t; + +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); + exit (1); +} + +static void print_region (struct region_t *region) +{ + printf ("0x%8lx - 0x%8lx, length: 0x%8lx, protection: %c%c%c, max_protection: %c%c%c\n", + region->address, region->address + region->size, region->size, + (region->protection & VM_PROT_READ) ? 'r' : '-', + (region->protection & VM_PROT_WRITE) ? 'w' : '-', + (region->protection & VM_PROT_EXECUTE) ? 'x' : '-', + (region->max_protection & VM_PROT_READ) ? 'r' : '-', + (region->max_protection & VM_PROT_WRITE) ? 'w' : '-', + (region->max_protection & VM_PROT_EXECUTE) ? 'x' : '-'); +} + +static void print_regions (struct region_t *regions) +{ + while (regions != NULL) + { + print_region (regions); + regions = regions->next; + } +} + +static void print_section (struct section *section) +{ + printf ("0x%8lx - 0x%8lx, length: 0x%8lx, offset: 0x%8lx\n", + section->addr, section->addr + section->size, section->size, section->offset); +} + +static void print_sections (section_list_t *sections) +{ + while (sections != NULL) + { + print_section (&(sections->section)); + sections = sections->next; + } +} + +static section_list_t *create_new_section_list(struct section *section_pointer) +{ + section_list_t *section_list; + + section_list = malloc (sizeof (section_list_t)); + section_list->next = NULL; + section_list->section = *section_pointer; + + return section_list; +} + +static void append_section_list(section_list_t **first_list, section_list_t *last_list) +{ + section_list_t *current; + + if (*first_list == NULL) { + *first_list = last_list; + return; + } + + current = *first_list; + while (current->next != NULL) + current = current->next; + + current->next = last_list; +} + +static void free_section_list(section_list_t *section_list) +{ + section_list_t *next; + + while (section_list != NULL) + { + next = section_list->next; + free(section_list); + section_list = next; + } +} + +static void add_sections_from_segment(section_list_t **all_sections, struct segment_command *segment) +{ + struct section *section_pointer; + int index; + + section_pointer = (struct section *)(segment + 1); + for (index = 0; index < segment->nsects; index++) { + append_section_list (all_sections, create_new_section_list (section_pointer)); + section_pointer++; + } +} + +static int section_with_address (section_list_t *sections, unsigned long address) +{ + int current_section, found_section; + + found_section = 0; + current_section = 1; + while (sections != NULL) + { + if (address >= sections->section.addr && address < sections->section.addr + sections->section.size) { + found_section = current_section; + break; + } + sections = sections->next; + current_section++; + } + + return found_section; +} + +/* + * Copy len bytes from ffd@fpos to tfd@tpos. + * If both file descriptors are -1, copy in memory (handles overlapping copies). + * If either ffd or tfd are -1, either read or write len bytes. + */ + +static void mcopy (int ffd, int tfd, + unsigned long fpos, unsigned long tpos, unsigned long len, char *reason) +{ + if ((ffd == -1) && (tfd == -1)) + { + char *f, *t, *e; + if (fpos > tpos) + { + f = (char *)fpos; + t = (char *)tpos; + e = (char *)(fpos + len); + while (f < e) *t++ = *f++; + } + else if (tpos > fpos) + { + f = (char *)(fpos + len); + t = (char *)(tpos + len); + e = (char *)fpos; + while (f > e) *--t = *--f; + } +#ifdef SHOW_MCOPY_READS + printf ("read: %10lu - %10lu, length: %10lu [from MEM] (%s)\n", tpos, tpos+len, len, reason); +#endif + } + else if (ffd == -1) + { + if (lseek (tfd, tpos, L_SET) < 0) + fatal_unexec ("cannot seek target"); + if (write (tfd, (void *)fpos, len) != len) + fatal_unexec ("cannot write target"); +#ifdef SHOW_MCOPY_WRITES + printf ("write: %10lu - %10lu, length: %10lu [from MEM] (%s)\n", tpos, tpos+len, len, reason); +#endif + } + else if (tfd == -1) + { + if (lseek (ffd, fpos, L_SET) < 0) + fatal_unexec ("cannot seek source"); + if (read (ffd, (void *)tpos, len) != len) + fatal_unexec ("cannot read source"); +#ifdef SHOW_MCOPY_READS + printf ("read: %10lu - %10lu, length: %10lu [from DISK] (%s)\n", tpos, tpos+len, len, reason); +#endif + } + else + { + int bread; + char *buf = alloca (1 << 16); + +#ifdef SHOW_MCOPY_WRITES + printf ("write: %10lu - %10lu, length: %10lu [from DISK] (%s)\n", tpos, tpos+len, len, reason); +#endif + + if (lseek (ffd, fpos, L_SET) < 0) + fatal_unexec ("cannot seek source"); + + if (lseek (tfd, tpos, L_SET) < 0) + fatal_unexec ("cannot seek target"); + + while((len > 0) && (bread = read (ffd, buf, MIN(1 << 16, len))) > 0) + { + if (bread < 0) + fatal_unexec ("cannot read source"); + if (write (tfd, buf, bread) != bread) + fatal_unexec ("cannot write target"); + len -= bread; + } + } +} + +/* + * The process of dumping (or unexecing) is the opposite of exec(). + * It takes the original executable and parts of memory that have been + * loaded with data, and creates a new executable. This allows + * standard lisp files to be loaded "instantly", because they are part + * of the executable. + * + * This involves using vm_region() to build a list of allocated memory + * regions, combining adjacent "similar" regions to reduce their + * number, skipping read-only regions and parts of regions covered by + * non-data segment load commands, and finally replacing the (usually + * one) data segment with a new segment for each region. + * + * File offsets in load commands that follow the data segment must be + * adjusted by the change in size of the data segment. The size of + * the load commands can increase without affecting file offsets -- + * see the note below. + * + * Data associated with the LC_SYMTAB and LC_DYSYMTAB is found in the + * __LINKEDIT segment -- there is no extra data to be written for + * these load commands. + * + * Relocatable symbols from the data segment, which we took from + * memory, need to be unrelocated. The relocatable address is found + * in the new mach-o file and then zeroed out. Failure to do this + * typically results in a segmentation fault, with the offending + * address being double what it is at the same point in temacs, since + * it has been relocated twice. + * + * Be sure to study the loader.h file if you want to understand this. + * otool -lv shows the load commands of the file, and is very useful + * when debugging this code. Also, 'size -m -x -l' gives a short + * list of the sections, and 'nm -maxp' and 'nm -map' are useful + * for the symbol table stuff. + * + * Note: This is not obvious, but the __TEXT section usually has a + * file offset of 0, and so when it is written it will overwrite + * any mach headers or load commands that have already been + * written... How much room is there before critial parts are + * overwritten when we add load commands? + * + * -- Steve Nygard + */ + +static void unexec_doit(int infd,int outfd) +{ + int i, j, l, header_position, output_position; + region_t *regions = NULL, *cregion, **pregions; + struct mach_header mach_header; + struct load_command *load_command, *original_load_commands; + struct segment_command *segment_pointer; + struct symtab_command *symtab_pointer; + struct section *section_pointer; + section_list_t *all_sections = NULL; + + unsigned long delta = 0; +#if defined(NS_TARGET) || !defined(NeXT) + struct dysymtab_command *dysymtab; + struct twolevel_hints_command *hinttab; + unsigned long extreloff = 0; + unsigned long nextrel = 0; + unsigned long locreloff = 0; + unsigned long nlocrel = 0; + struct relocation_info reloc_info; + unsigned long fixed_reloc_count = 0; +#endif + + struct segment_command new_data_segment; + section_list_t *original_sections, *new_sections, **sect_ptr, *section_item; + + malloc_cookie = malloc_freezedry(); +#ifdef VERBOSE + printf ("malloc_cookie: %lx\n", malloc_cookie); +#endif + if (malloc_cookie == 0) + { + fprintf(stderr, "Error in malloc_freezedry()\n"); + abort(); + } + + { + vm_address_t address; + vm_size_t size; + mach_port_t object_name; +#ifdef DARWIN + task_t task = mach_task_self(); + struct vm_region_basic_info info; + mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT; +#else + task_t task = task_self(); + vm_prot_t protection, max_protection; + vm_inherit_t inheritance; + boolean_t shared; + vm_offset_t offset; +#endif + + for (address = VM_MIN_ADDRESS, pregions = ®ions; +#ifdef DARWIN + vm_region(task, &address, &size, VM_REGION_BASIC_INFO, + (vm_region_info_t)&info, &info_count, &object_name) == KERN_SUCCESS; +#else + vm_region(task, &address, &size, &protection, &max_protection, + &inheritance, &shared, &object_name, &offset) == KERN_SUCCESS; +#endif + address += size) + { + (*pregions) = alloca (sizeof(region_t)); + (*pregions)->address = address; + (*pregions)->size = size; +#ifdef DARWIN + (*pregions)->protection = info.protection; + (*pregions)->max_protection = info.max_protection; +#else + (*pregions)->protection = protection; + (*pregions)->max_protection = max_protection; +#endif + (*pregions)->file_offset = 0; + (*pregions)->file_size = 0; + (*pregions)->next = 0; + pregions = &((*pregions)->next); +#ifdef DARWIN + if (object_name != MACH_PORT_NULL) + mach_port_deallocate(mach_task_self(), object_name); + info_count = VM_REGION_BASIC_INFO_COUNT; +#endif + } + } +#ifdef VERBOSE + printf ("Regions.\n"); + print_regions (regions); + printf ("----------------------------------------------------------------------\n"); +#endif + + /* + * Concatenate regions that are adjacent in memory and share the same + * protection attributes. + */ + + for (cregion = regions; cregion; cregion = cregion->next) + { + while ((cregion->next) && + (cregion->next->address == cregion->address + cregion->size) && + (cregion->next->protection == cregion->protection) && + (cregion->next->max_protection == cregion->max_protection)) + { + cregion->size += cregion->next->size; + cregion->next = cregion->next->next; + } + } +#ifdef VERBOSE + printf ("Concatenated regions.\n"); + print_regions (regions); + printf ("----------------------------------------------------------------------\n"); +#endif + + /* + * Remove read-only regions, and regions above a fixed limit. + * Could have been done before allocating, but this way we can show + * the regions before and after while debugging. + */ + + for (pregions = ®ions; *pregions != NULL;) + { + if ( !((*pregions)->protection & VM_PROT_WRITE) + || ((*pregions)->address >= 0x3000000)) + { + *pregions = (*pregions)->next; + } + else + { + pregions = &((*pregions)->next); + } + } +#ifdef VERBOSE + printf ("Skipped regions.\n"); + print_regions (regions); + printf ("----------------------------------------------------------------------\n"); +#endif + /* + * Read original mach header and load commands. + */ + + mcopy (infd, -1, 0, (unsigned long) &mach_header, sizeof(mach_header), "read original mach header"); + original_load_commands = alloca (mach_header.sizeofcmds); + mcopy (infd, -1, sizeof(mach_header), (unsigned long) original_load_commands, mach_header.sizeofcmds, + "read original load comands"); + + /* + * Skip (or adjust) regions that intersect memory represented by non-data + * segments from the original load commands. + */ + + for (pregions = ®ions; *pregions;) + { + for (load_command = original_load_commands, i = 0; + i < mach_header.ncmds; + i++, load_command = (struct load_command *)(((void *)load_command) + load_command->cmdsize)) + { + unsigned long ob, oe; + segment_pointer = (struct segment_command *)load_command; + if (segment_pointer->cmd != LC_SEGMENT || (strcmp (segment_pointer->segname, SEG_DATA) == 0)) continue; + ob = MAX((*pregions)->address, segment_pointer->vmaddr); + oe = MIN((*pregions)->address + (*pregions)->size, segment_pointer->vmaddr + segment_pointer->vmsize); + if (ob >= oe) continue; + if (ob == (*pregions)->address) + { + if (oe == (*pregions)->address + (*pregions)->size) + { + goto skip_region; + } + else + { + (*pregions)->address = oe; + (*pregions)->size -= (oe - ob); + } + } + else + { + if (oe == (*pregions)->address + (*pregions)->size) + { + (*pregions)->size -= (oe - ob); + } + else + { + cregion = alloca (sizeof(*cregion)); + cregion->address = oe; + cregion->size = ((*pregions)->address + (*pregions)->size) - oe; + cregion->protection = (*pregions)->protection; + cregion->max_protection = (*pregions)->max_protection; + cregion->file_offset = 0; + cregion->file_size = 0; + cregion->next = (*pregions)->next; + (*pregions)->size = ob - (*pregions)->address; + (*pregions)->next = cregion; + } + } + } + + pregions = &((*pregions)->next); + continue; + + skip_region: + *pregions = (*pregions)->next; + } +#ifdef VERBOSE + printf ("Munged regions (1).\n"); + print_regions (regions); + printf ("----------------------------------------------------------------------\n"); +#endif + + for (load_command = original_load_commands, i = mach_header.ncmds, header_position = sizeof(mach_header), output_position = 0; + i > 0; + i--, load_command = (struct load_command *)(((void *)load_command) + load_command->cmdsize)) + { + switch (load_command->cmd) + { + case LC_SEGMENT: + segment_pointer = (struct segment_command *)load_command; + + if (strcmp (segment_pointer->segname, SEG_DATA) == 0) + { +#if 1 + unsigned long current_address; + + original_sections = NULL; + new_sections = NULL; + sect_ptr = &original_sections; + + section_pointer = (struct section *)(segment_pointer + 1); + for (l = 0; l < segment_pointer->nsects; l++) + { + if (!strncmp (section_pointer->sectname, "__la_symbol_ptr", 16)) + { + section_item = alloca (sizeof (section_list_t)); + section_item->next = *sect_ptr; + section_item->section = *section_pointer; + *sect_ptr = section_item; + sect_ptr = &(section_item->next); + } + else if (!strncmp (section_pointer->sectname, "__nl_symbol_ptr", 16)) + { + section_item = alloca (sizeof (section_list_t)); + section_item->next = *sect_ptr; + section_item->section = *section_pointer; + *sect_ptr = section_item; + sect_ptr = &(section_item->next); + } + else if (!strncmp (section_pointer->sectname, "__dyld", 16)) + { + section_item = alloca (sizeof (section_list_t)); + section_item->next = *sect_ptr; + section_item->section = *section_pointer; + *sect_ptr = section_item; + sect_ptr = &(section_item->next); + } + + section_pointer++; + } + + cregion = regions; + /* new_data_segment */ + new_data_segment.cmd = LC_SEGMENT; + strncpy (new_data_segment.segname, SEG_DATA, 16); + new_data_segment.vmaddr = cregion->address; + new_data_segment.vmsize = 0; + new_data_segment.fileoff = 0; + new_data_segment.filesize = 0; + new_data_segment.maxprot = cregion->max_protection; + new_data_segment.initprot = cregion->protection; + new_data_segment.flags = segment_pointer->flags; + new_data_segment.nsects = 0; + new_data_segment.cmdsize = sizeof (struct segment_command); +#ifdef VERBOSE + printf ("Original sections:\n"); + print_sections (original_sections); + printf ("----------------------------------------------------------------------\n"); +#endif + /* Create list of new segments */ + sect_ptr = &new_sections; + current_address = new_data_segment.vmaddr; + while (original_sections != NULL) + { + if (current_address < original_sections->section.addr) + { + /* Create new section for this. */ + section_item = alloca (sizeof (section_list_t)); + section_item->next = *sect_ptr; + + section_pointer = &(section_item->section); + strncpy (section_pointer->sectname, "__data", 16); + strncpy (section_pointer->segname, SEG_DATA, 16); + section_pointer->addr = current_address; + section_pointer->size = original_sections->section.addr - current_address; + section_pointer->offset = 0; + section_pointer->align = 2; /* Yuck. */ + section_pointer->reloff = 0; + section_pointer->nreloc = 0; + section_pointer->flags = 0; /* S_REGULAR? */ + section_pointer->reserved1 = 0; + section_pointer->reserved2 = 0; + + *sect_ptr = section_item; + sect_ptr = &(section_item->next); + current_address = original_sections->section.addr; + } + + /* Put/copy this section into new list */ + section_item = original_sections; + original_sections = original_sections->next; + section_item->next = *sect_ptr; /* Should be NULL... */ + *sect_ptr = section_item; + sect_ptr = &(section_item->next); + + /* increase current address */ + current_address += section_item->section.size; + } + /* if current address < end of region, add final section. */ + if (current_address < cregion->address + cregion->size) + { + /* Create new section for this. */ + section_item = alloca (sizeof (section_list_t)); + section_item->next = *sect_ptr; + + section_pointer = &(section_item->section); + strncpy (section_pointer->sectname, "__data", 16); + strncpy (section_pointer->segname, SEG_DATA, 16); + section_pointer->addr = current_address; + section_pointer->size = cregion->address + cregion->size - current_address; + section_pointer->offset = 0; + section_pointer->align = 2; /* Yuck. */ + section_pointer->reloff = 0; + section_pointer->nreloc = 0; + section_pointer->flags = 0; /* S_REGULAR? */ + section_pointer->reserved1 = 0; + section_pointer->reserved2 = 0; + + *sect_ptr = section_item; + sect_ptr = &(section_item->next); + + } +#ifdef VERBOSE + printf ("New sections:\n"); + print_sections (new_sections); + printf ("----------------------------------------------------------------------\n"); +#endif + /** + * Go through new list of sections + * - write section to disk, either from memory or original file + * - say, if offset == 0, take from memory, otherwise from original file at that offset + * - set offset of section + * - set fileoff of segment to be that of the first section + * - increase output position + **/ + + sect_ptr = &new_sections; + while (*sect_ptr != NULL) + { + section_pointer = &((*sect_ptr)->section); + if (new_data_segment.fileoff == 0) + new_data_segment.fileoff = output_position; + new_data_segment.vmsize += section_pointer->size; + new_data_segment.filesize += section_pointer->size; + new_data_segment.nsects++; + new_data_segment.cmdsize += sizeof (struct section); + printf ("section is '%s'\n", section_pointer->sectname); + if (section_pointer->offset == 0) + { + mcopy (-1, outfd, (unsigned long) section_pointer->addr, output_position, section_pointer->size, + "SEG_DATA: write section data from memory"); + } + else + { + mcopy (infd, outfd, (unsigned long) section_pointer->offset, output_position, section_pointer->size, + "SEG_DATA: write section data from original file"); + } + section_pointer->offset = output_position; + output_position += section_pointer->size; + + sect_ptr = &((*sect_ptr)->next); + } + + /* Write data segment and sections, increasing the header position */ + mcopy (-1, outfd, (unsigned long) &new_data_segment, header_position, sizeof (struct segment_command), + "SEG_DATA: write segment command"); + header_position += sizeof (struct segment_command); + while (new_sections != NULL) + { + mcopy (-1, outfd, (unsigned long) &(new_sections->section), header_position, sizeof (struct section), + "SEG_DATA: write section command"); + // Need to add this section to a list of all the sections + header_position += sizeof (struct section); + append_section_list (&all_sections, create_new_section_list (&(new_sections->section))); + new_sections = new_sections->next; + } + mach_header.ncmds++; + + /* Finally, skip first data segment. */ + regions = regions->next; +#endif + +#if 1 + /* Write remainder of regions as data segments */ + mach_header.ncmds--; + j = segment_pointer->cmdsize; /* Save original command size for loop. */ + for (cregion = regions; cregion != NULL; cregion = cregion->next) + { + mcopy (-1, outfd, cregion->address, output_position, cregion->size, + "SEG_DATA: write remainder data"); + segment_pointer->cmd = LC_SEGMENT; + segment_pointer->cmdsize = sizeof(*segment_pointer); + strncpy (segment_pointer->segname, SEG_DATA, sizeof(segment_pointer->segname)); + segment_pointer->vmaddr = cregion->address; + segment_pointer->vmsize = cregion->size; + segment_pointer->filesize = cregion->size; + segment_pointer->maxprot = cregion->max_protection; + segment_pointer->initprot = cregion->protection; + segment_pointer->nsects = 0; + segment_pointer->flags = 0; + segment_pointer->fileoff = output_position; + output_position += segment_pointer->filesize; + mcopy (-1, outfd, (unsigned long)segment_pointer, header_position, segment_pointer->cmdsize, + "SEG_DATA: write segment command for remainder data"); + header_position += segment_pointer->cmdsize; + mach_header.ncmds++; + + cregion->file_offset = segment_pointer->fileoff; + cregion->file_size = segment_pointer->filesize; + } + segment_pointer->cmdsize = j; + +#endif + } + else + { +#ifdef VERBOSE + printf ("segment is '%s':\n", segment_pointer->segname); +#endif + mcopy (infd, outfd, segment_pointer->fileoff, output_position, segment_pointer->filesize, + "SEG_OTHER: write segment data"); + section_pointer = (struct section *) (((void *)segment_pointer)+sizeof(*segment_pointer)); + for(j = 0; j < segment_pointer->nsects; j++) + { + if (section_pointer[j].offset != 0) + section_pointer[j].offset = (section_pointer[j].offset - segment_pointer->fileoff) + output_position; + if (section_pointer[j].reloff != 0) + section_pointer[j].reloff = (section_pointer[j].reloff - segment_pointer->fileoff) + output_position; + } + + if (strcmp (segment_pointer->segname, SEG_LINKEDIT) == 0) + { + delta = output_position - segment_pointer->fileoff; + } + + segment_pointer->fileoff = output_position; + output_position += segment_pointer->filesize; + + mcopy (-1, outfd, (unsigned long)load_command, header_position, load_command->cmdsize, + "SEG_OTHER: write segment command and its sections"); + header_position += load_command->cmdsize; + + // Now, scan the segments for sections, so we have a list of all the sections to use to fix up + // the symbol table entries. + add_sections_from_segment(&all_sections, segment_pointer); + } + break; + + case LC_SYMTAB: + { + struct nlist *symtab; + + symtab_pointer = (struct symtab_command *)load_command; + + symtab = malloc(symtab_pointer->nsyms * sizeof(struct nlist)); + mcopy(infd, -1, symtab_pointer->symoff, (unsigned long)symtab, symtab_pointer->nsyms * sizeof(struct nlist), + "Read old symbol table into memory"); + + symtab_pointer->symoff += delta; + symtab_pointer->stroff += delta; + mcopy (-1, outfd, (unsigned long)load_command, header_position, load_command->cmdsize, + "write symtab command"); + header_position += load_command->cmdsize; + printf ("LC_SYMTAB: symoff = %ld, nsyms = %ld, stroff = %ld, strsize = %ld\n", + symtab_pointer->symoff, symtab_pointer->nsyms, symtab_pointer->stroff, symtab_pointer->strsize); + + // We've already written out the symbol table, but we're going to read it back in, adjust the + // symbol table entries, and write out the result again. + + if (all_sections != NULL) + { + int index; + struct nlist *nlist_pointer; + section_list_t *section; + int section_index; + int changed_symtabs; + + printf ("All sections:\n"); + print_sections (all_sections); + + changed_symtabs = 0; + nlist_pointer = symtab; + + for (index = 0; index < symtab_pointer->nsyms; index++) { + if ((nlist_pointer->n_type & N_TYPE) == N_SECT) { + section_index = section_with_address(all_sections, nlist_pointer->n_value); +#if 0 + printf ("%5d: 0x%08lx 0x%02x 0x%02x (0x%02x) 0x%04x 0x%08lx\n", + index, nlist_pointer->n_un.n_strx, nlist_pointer->n_type & 0xff, nlist_pointer->n_sect & 0xff, + section_index, + nlist_pointer->n_desc & 0xffff, nlist_pointer->n_value); +#endif + if (nlist_pointer->n_sect != section_index) { + nlist_pointer->n_sect = section_index; + changed_symtabs++; + } + } + nlist_pointer++; + } + + printf ("Adjusted n_sect for %d symbol table entries.\n", changed_symtabs); + mcopy(-1, outfd, (unsigned long)symtab, symtab_pointer->symoff, symtab_pointer->nsyms * sizeof(struct nlist), + "write updated symbol table"); + + free_section_list(all_sections); + } + + free(symtab); + } + break; +#if defined(NS_TARGET) || !defined(NeXT) + case LC_DYSYMTAB: + dysymtab = (struct dysymtab_command *)load_command; + extreloff = dysymtab->extreloff; + nextrel = dysymtab->nextrel; + + locreloff = dysymtab->locreloff; + nlocrel = dysymtab->nlocrel; + + if (dysymtab->nindirectsyms > 0) { + dysymtab->indirectsymoff += delta; + } + if (nextrel > 0) { + dysymtab->extreloff += delta; + } + + if (nlocrel > 0) { + dysymtab->locreloff += delta; + } + mcopy (-1, outfd, (unsigned long)load_command, header_position, load_command->cmdsize, + "write dysymtab command"); + header_position += load_command->cmdsize; + + break; + + case LC_TWOLEVEL_HINTS: + hinttab = (struct twolevel_hints_command *)load_command; + hinttab->offset += delta; + + mcopy (-1, outfd, (unsigned long)load_command, header_position, load_command->cmdsize, + "write two-level hint command"); + header_position += load_command->cmdsize; + + break; +#endif + default: + { + char *reason, *cmdstr; + + /* Create a string that tells what load command is being left + * alone. */ + switch (load_command->cmd) + { + case LC_UNIXTHREAD: + cmdstr = "LC_UNIXTHREAD"; + break; + case LC_LOAD_DYLIB: + cmdstr = "LC_LOAD_DYLIB"; + break; + case LC_LOAD_DYLINKER: + cmdstr = "LC_LOAD_DYLINKER"; + break; + default: + cmdstr = NULL; + } + if (cmdstr != NULL) + { + asprintf(&reason, "write other load command (%s)", cmdstr); + } + else + { + asprintf(&reason, "write other load command (0x%x)", load_command->cmd); + } + + mcopy (-1, outfd, (unsigned long)load_command, header_position, load_command->cmdsize, + reason); + free(reason); + header_position += load_command->cmdsize; + } + } + } + + mach_header.sizeofcmds = header_position - sizeof(mach_header); + mcopy (-1, outfd, (unsigned long) &mach_header, 0, sizeof(mach_header), "write mach header"); + +#if defined(NS_TARGET) || !defined(NeXT) + if (mach_header.flags & MH_PREBOUND) { + /* Don't mess with prebound executables */ + return; + } + + /* + * Fix up relocation entries in the data segment(s). + */ + if (lseek (infd, locreloff, L_SET) < 0) + fatal_unexec ("cannot seek input file"); + + fixed_reloc_count = 0; + for (i = 0; i < nlocrel; i++) + { + long zeroval = 0; + struct scattered_relocation_info *si; + + if (read (infd, &reloc_info, sizeof(reloc_info)) != sizeof(reloc_info)) + fatal_unexec ("cannot read input file"); + +#if 1 +#ifdef VERBOSE + printf ("%2d: reloc: %lx, start: %lx, end: %lx\n", i, reloc_info.r_address, + new_data_segment.vmaddr, new_data_segment.vmaddr + new_data_segment.filesize); +#endif + if (reloc_info.r_address >= new_data_segment.vmaddr + && reloc_info.r_address < new_data_segment.vmaddr + new_data_segment.filesize) + { + fixed_reloc_count++; + mcopy (-1, outfd, (unsigned long) &zeroval, + new_data_segment.fileoff + reloc_info.r_address - new_data_segment.vmaddr, + 1 << reloc_info.r_length, "fix local relocation entry"); + } +#endif + } + printf ("Fixed %lu/%lu local relocation entries in data segment(s).\n", fixed_reloc_count, nlocrel); + + if (lseek (infd, extreloff, L_SET) < 0) + fatal_unexec ("cannot seek input file"); + + for (i = 0; i < nextrel; i++) + { + long zeroval = 0; + + if (read (infd, &reloc_info, sizeof(reloc_info)) != sizeof(reloc_info)) + fatal_unexec ("cannot read input file"); + +#if 1 +#ifdef VERBOSE + printf ("%2d: reloc: %lx, start: %lx, end: %lx\n", i, reloc_info.r_address, + new_data_segment.vmaddr, new_data_segment.vmaddr + new_data_segment.filesize); +#endif + if (reloc_info.r_address >= new_data_segment.vmaddr + && reloc_info.r_address < new_data_segment.vmaddr + new_data_segment.filesize) + { + fixed_reloc_count++; + mcopy (-1, outfd, (unsigned long) &zeroval, + new_data_segment.fileoff + reloc_info.r_address - new_data_segment.vmaddr, + 1 << reloc_info.r_length, "fix external relocation entry"); + } +#endif + } + + printf ("Fixed %lu/%lu external relocation entries in data segment(s).\n", fixed_reloc_count, nextrel); + +#endif +} + +void unexec (char *outfile, char *infile) +{ + char tmpfile[MAXPATHLEN + 1]; + int infd, outfd; + + if ((infd = open (infile, O_RDONLY, 0)) < 0) + fatal_unexec ("cannot open input file `%s'", infile); + + strcpy (tmpfile, outfile); + strcat (tmpfile, "-temp"); + + if ((outfd = open (tmpfile, O_RDWR|O_TRUNC|O_CREAT, 0755)) < 0) + fatal_unexec ("cannot open temporary output file `%s'", tmpfile); + + unexec_doit (infd, outfd); + + close (infd); + close (outfd); + if (rename (tmpfile, outfile) < 0) + { + unlink (tmpfile); + fatal_unexec ("cannot rename `%s' to `%s'", tmpfile, outfile); + } +} Index: emacs/src/unexnext.c =================================================================== RCS file: /cvs/Darwin/src/live/emacs/emacs/src/unexnext.c,v retrieving revision 1.1.1.5 retrieving revision 1.3 diff -u -r1.1.1.5 -r1.3 Index: emacs/src/m/powermacintosh.h =================================================================== RCS file: powermacintosh.h diff -N powermacintosh.h --- /dev/null Tue Sep 17 14:45:13 2002 +++ emacs/src/m/powermacintosh.h Tue Sep 17 16:29:09 2002 @@ -0,0 +1,45 @@ +/* Apple Power Macintosh machine/system dependent defines + Copyright (C) 1997 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +/* The following line tells the configuration script what sort of + operating system this machine is likely to run. + USUAL-OPSYS="darwin" */ + +/* Define WORDS_BIG_ENDIAN iff lowest-numbered byte in a word + is the most significant byte. */ + +#define WORDS_BIG_ENDIAN + +/* Define NO_ARG_ARRAY if you cannot take the address of the first of a + * group of arguments and treat it as an array of the arguments. */ + +#define NO_ARG_ARRAY + +/* Use type int rather than a union, to represent Lisp_Object */ +/* This is desirable for most machines. */ + +#define NO_UNION_TYPE + +/* Define addresses, macros, change some setup for dump */ + +#define NO_REMAP + +#define DATA_SEG_BITS 0 Index: emacs/src/s/darwin.h =================================================================== RCS file: darwin.h diff -N darwin.h --- /dev/null Tue Sep 17 14:45:13 2002 +++ emacs/src/s/darwin.h Tue Sep 17 16:29:09 2002 @@ -0,0 +1,104 @@ +/* Configuration file for Darwin OS. + Copyright (C) 1997 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* We give these symbols the numeric values found in to + avoid warnings about redefined macros. */ +#define BSD 199506 +#define BSD4_3 1 +#define BSD4_4 1 + +#include "bsd4-3.h" + +/* SYSTEM_TYPE should indicate the kind of system you are using. + It sets the Lisp variable system-type. We'll need to undo the bsd one. */ + +#undef SYSTEM_TYPE +#define SYSTEM_TYPE "darwin" + +#ifndef DARWIN +#define DARWIN +#endif + +#undef KERNEL_FILE +#define KERNEL_FILE "/mach_kernel" + +#define HAVE_ALLOCA + +#define HAVE_MACH_MACH_H + +#define SYSTEM_MALLOC + +#define WAIT_USE_INT + +#define SOCKLEN_TYPE int + +#define GETPGRP_NO_ARG + +#ifdef HAVE_LIBNCURSES +#define TERMINFO +#define LIBS_TERMCAP -lncurses +#else +#define TERMCAP_FILE "/usr/share/misc/termcap" +#endif + +#define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_p - (FILE)->_bf._base) + +#define A_OUT_H_FILE + +/* Data type of load average, as read out of kmem. */ +#define LOAD_AVE_TYPE long + +#define ABORT_RETURN_TYPE __private_extern__ void + +/* Convert that into an integer that is 100 for a load average of 1.0 */ +#define LOAD_AVE_CVT(x) (int) (((double)(x)) * 100.0 / FSCALE) + +#define UNEXEC unexdyld.o + +/* Definitions for how to compile & link. */ + +/* Link this program just by running cc. */ +#define ORDINARY_LINK + +/* #define C_SWITCH_SYSTEM */ + +/* We don't have a g library, so override the -lg LIBS_DEBUG switch */ +#define LIBS_DEBUG + +/* Adding -lm confuses the dynamic linker, so omit it. */ +#define LIB_MATH + +/* Definitions for how to dump. */ + +#define START_FILES pre-crt0.o + +/* start_of_text isn't actually used, so make it compile without error. */ +#define TEXT_START (0) + +/* This seems to be right for end_of_text, but it may not be used anyway. */ +#define TEXT_END get_etext() + +/* This seems to be right for end_of_data, but it may not be used anyway. */ +#define DATA_END get_edata() + +/* Don't close pty in process.c to make it a controlling terminal. It is + * already the controlling terminal of the subprocess, because we did ioctl + * TIOCSCTTY. */ +#define DONT_REOPEN_PTY Index: emacs/src/s/rhapsody.h =================================================================== RCS file: rhapsody.h diff -N rhapsody.h --- /dev/null Tue Sep 17 14:45:13 2002 +++ emacs/src/s/rhapsody.h Tue Sep 17 16:29:09 2002 @@ -0,0 +1,89 @@ +/* Configuration file for Mac OS X Server. + Copyright (C) 1997 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* We give these symbols the numeric values found in to + avoid warnings about redefined macros. */ +#define BSD 199506 +#define BSD4_3 1 +#define BSD4_4 1 + +#include "bsd4-3.h" + +/* SYSTEM_TYPE should indicate the kind of system you are using. + It sets the Lisp variable system-type. We'll need to undo the bsd one. */ + +#undef SYSTEM_TYPE +#define SYSTEM_TYPE "apple-rhapsody" + +#ifndef RHAPSODY +#define RHAPSODY +#endif + +#define HAVE_ALLOCA + +#define HAVE_MACH_MACH_H + +#define SYSTEM_MALLOC + +#define WAIT_USE_INT + +#define SOCKLEN_TYPE int + +#define GETPGRP_NO_ARG + +#define TERMCAP_FILE "/usr/share/misc/termcap" + +#define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_p - (FILE)->_bf._base) + +#define A_OUT_H_FILE + +/* 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 LOAD_AVE_CVT(x) (int) (((double)(x)) * 100.0 / FSCALE) + +#define UNEXEC unexdyld.o + +/* Definitions for how to compile & link. */ + +/* Link this program just by running cc. */ +#define ORDINARY_LINK + +/* #define C_SWITCH_SYSTEM */ + +/* We don't have a g library, so override the -lg LIBS_DEBUG switch */ +#define LIBS_DEBUG + +/* Adding -lm confuses the dynamic linker, so omit it. */ +#define LIB_MATH + + /* Definitions for how to dump. */ + +#define START_FILES pre-crt0.o + +/* start_of_text isn't actually used, so make it compile without error. */ +#define TEXT_START (0) + +/* This seems to be right for end_of_text, but it may not be used anyway. */ +#define TEXT_END get_etext() + +/* This seems to be right for end_of_data, but it may not be used anyway. */ +#define DATA_END get_edata() Index: emacs/configure --- configure.orig Tue Oct 19 23:56:50 2004 +++ configure Tue Oct 19 23:58:32 2004 @@ -1179,6 +1179,24 @@ machine=hp800 opsys=nextstep ;; + ## Mac OS X Server + *-*-rhapsody*) + opsys=rhapsody + case "${canonical}" in + powerpc-*-rhapsody*) machine=powermacintosh ;; + i386-*-rhapsody*) machine=intel386 ;; + esac + ;; + + ## Darwin / Mac OS X + *-*-darwin*) + opsys=darwin + case "${canonical}" in + powerpc-*-darwin*) machine=powermacintosh ;; + i?86-*-darwin*) machine=intel386 ;; + esac + ;; + ## Orion machines orion-orion-bsd* ) machine=orion opsys=bsd4-2 Index: emacs/configure.in --- configure.in.orig Tue Oct 19 23:56:54 2004 +++ configure.in Tue Oct 19 23:59:29 2004 @@ -553,6 +553,24 @@ machine=hp800 opsys=nextstep ;; + ## Mac OS X Server + *-*-rhapsody*) + opsys=rhapsody + case "${canonical}" in + powerpc-*-rhapsody*) machine=powermacintosh ;; + i386-*-rhapsody*) machine=intel386 ;; + esac + ;; + + ## Darwin / Mac OS X + *-*-darwin*) + opsys=darwin + case "${canonical}" in + powerpc-*-darwin*) machine=powermacintosh ;; + i?86-*-darwin*) machine=intel386 ;; + esac + ;; + ## Orion machines orion-orion-bsd* ) machine=orion opsys=bsd4-2