Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!seismo!husc6!necntc!ima!haddock!karl
From: karl@haddock.ISC.COM (Karl Heuer)
Newsgroups: comp.emacs
Subject: Re: GNU exists on IBM RT running AIX
Message-ID: <711@haddock.ISC.COM>
Date: Fri, 10-Jul-87 19:10:04 EDT
Article-I.D.: haddock.711
Posted: Fri Jul 10 19:10:04 1987
Date-Received: Sun, 12-Jul-87 12:48:46 EDT
References: <640@haddock.UUCP>
Reply-To: karl@haddock.ISC.COM.UUCP (Karl Heuer)
Distribution: world
Organization: Interactive Systems, Boston
Lines: 64
Summary: Part 1: unexec

Nearly two weeks ago I wrote in article <640@haddock.UUCP>:
>I have succeeded in bringing up Gnu Emacs under AIX, unexec and all.  Details
>later this week.

Sorry about the delay; I got sidetracked by other commitments.  Also I was
hoping to snarf a more recent copy of emacs before posting the diffs; 18.40 is
the latest we have here.  (If someone offers to send me 18.47, or makes it
available via UUCP from the 617 area code, I'd be most grateful.)

Anyway, here's the first installment, to get y'all started.  The existing
unexec code seems to know two formats, BSD and COFF.  AIX uses a variant of
COFF known as GPOFF.  Rather than attempt to hack the COFF code to make it
write GPOFF, I took the easy way out and wrote my own unexec() from scratch.
Some ambitious person should fold it (with #ifdef) into the existing unexec.c,
without making it such a special case.

This code writes a stripped a.out; it should be relatively easy to copy the
symbol table too.  I don't know of any way to make the initialized data
segment pure, so no special action is taken in that respect.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
---- cut here ----
#!/bin/sh
tr -d '\12' <<\EOF | tr '@' '\12' >unexec.c
#include "config.h"
@
@#include 
@#define	HSIZE	sizeof(struct exec)
@static struct exec hdr;
@extern etext;
@extern char *sbrk();
@
@#define	TBASE	0x10000000
@#define	DBASE	0x20000000
@#define	text_start	(TBASE+HSIZE)
@#define	text_end	((unsigned int)&etext)
@
@int unexec(name) char *name; {
@    register unsigned int data_start, data_end;
@    register int fd;
@    data_start = DBASE | (text_end & 0x7FF);
@    data_end = (unsigned int)sbrk(0);
@    hdr.a_magic[0] = A_MAGIC0;
@    hdr.a_magic[1] = A_MAGIC1;
@    hdr.a_flags = A_TOFF|A_EXEC|A_PURE;
@    hdr.a_cpu = A_SELF;
@    hdr.a_hdrlen = HSIZE;
@    hdr.a_text = text_end - text_start + HSIZE;
@    hdr.a_data = data_end - data_start;
@    hdr.a_bss = 0;
@    hdr.a_entry = (long)text_start;
@    hdr.a_tbase = TBASE;
@    hdr.a_dbase = (long)data_start;
@    if ((fd = creat(name, 0777)) < 0 || write(fd, (char *)&hdr, H
SIZE) != HSIZE || write(fd, (char *)text_start, text_end - text_st
art) != text_end - text_start || write(fd, (char *)data_start, dat
a_end - data_start) != data_end - data_start) {
@	close(fd);
@	error("Unable to unexec to %s", name);
@    }
@    close(fd);
@    return (0);
@}@
EOF