[comp.emacs] Gnu 18.50 on HP 9000 Series 800

bd@hpsemc.HP.COM (bob desinger) (03/30/88)

I just brought up Gnu Emacs 18.50 on our HP 9000 Series 800.  Here are
the changes you'll need to make to get it running on your machine if
you have an HP 9000 Model 825, 835, 840, or 850.  I had to bring up
HP-UX Version 2.0 (the new release) before I could get Emacs to work,
by the way.  The 2.0 compiler and optimizer work fine with Emacs, too.

In src/m-hp9000s800.h, add:
	#define	killpg(p,s)	kill(-(p), s)

In src/Makefile, add an extra rule under the xmakefile target to lose
some sed-postprocessing garbage.  This is on the next-to-the-last line
in the Makefile.
	sed '/^<TAB><SPACE><SPACE>$$/d'
Replace the <TAB> and <SPACE> strings with a real tab and space.
(In other words, change:

	sed -n -e '/^..*$$/p' > xmakefile
to
	sed -n -e '/^..*$$/p' | sed '/^	  $$/d' > xmakefile

where the whitespace in the last sed command is really a tab and two
spaces.)

The src/unexec.s800 file mentioned in etc/MACHINES has vanished from
the MIT master files and will not appear in the 18.50 distribution.
The person who submitted the hp9000s800 changes, Eric Decker, left HP
last week for cisco Systems.  I got his unexec.c for the s800 from his
master sources directory, and it appears below.  It will probably
never appear on the MIT master sources directory because RMS feels
that it's a maintenance burden to have more than one unexec.c.  (I
guess the people at Mips Computer and Xenix got their changes #ifdef'd
into unexec.c just in time.)

The symbolic debugger xdb gets a segmentation violation when trying to
debug Emacs.  The non-symbolic debugger adb drops a core when you ask
for a stack trace, so it's not useful either.  (Something about the
way unexec.c tweaks the a.out file, no doubt.)  So you might as well
make Emacs with C_OPTIMIZE_SWITCH (that is, -O) and save some runtime.
I also suggest setting the sticky bit (`chmod +t emacs') on the final
executable if more than one of you will be using it.  You can strip
the binary (before setting the sticky bit), but you won't save any
bytes.

bob desinger					bd%hpsemc@hplabs.HP.COM
HP Software Evaluation and Migration Center	uunet!hpda!hpsemc!bd


#! /bin/sh
# This is a shell archive.  Remove anything before this line,
# then unwrap it by saving it in a file and typing "sh file".
#
# Wrapped by bd at hpsemc on Tue Mar 29 16:29:10 1988
# Contents:
#	Changes.HP 	unexec.s800 	

PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:$PATH; export PATH
echo 'At the end, you should see the message "End of shell archive."'


echo Extracting Changes.HP
cat >Changes.HP <<'@//E*O*F Changes.HP//'
Tue Mar 22 15:35:02 1988  bob desinger  (bd at hpsemc)

	* src/m-hp9000s800.h:
	BSD's killpg(pid, sig) is handled by HP-UX's kill(-pid, sig).
	Define killpg() accordingly for src/sysdep.c.

Mon Mar 21 10:20:58 1988  bob desinger  (bd at hpsemc)

	* src/Makefile:
	The xmakefile contains a lone tab and two spaces on a line between
	the definition of cppdir and STARTFILES, causing `make' to poot.
	Output from `cc -E ymakefile | cat -v -e -t' shows no such line,
	so this is evidently caused by the sed postprocessing step.  The
	easiest way to fix this is to simply add an extra rule under the
	xmakefile target to lose the line:  sed '/^<TAB><SPACE><SPACE>$$/d'
@//E*O*F Changes.HP//

set `wc -lwc <Changes.HP`
if test $1 -ne 15 -o $2 -ne 108 -o $3 -ne 664
then	echo ! Changes.HP should have 15 lines, 108 words, and 664 characters
	echo ! but has $1 lines, $2 words, and $3 characters
fi
chmod 664 Changes.HP


echo Extracting unexec.s800
sed 's/^@//' >unexec.s800 <<'@//E*O*F unexec.s800//'
/*
 * Usage is
 *        undump new-a.out-file [old-a.out-file] [core-file]
 * where old-a.out-file and core-file default to "a.out" and "core",
 * respectively.
 * 
 * It doesn't preserve open files, and the program is re-entered at main
 * when you run it.
 */


/*
 * undump.c - Convert a core file to an a.out.
 *
 * Usage:
 * undump new-a.out [a.out] [core]
 */

#include <stdio.h>
#include <sys/param.h>
#include <sys/dir.h>
#include <sys/signal.h>
#include <sys/user.h>
#include <sys/stat.h>
#include <magic.h>

#include "config.h"

#define PSIZE	    10240

struct header hdr,ohdr;
unsigned datacnt;
unsigned datastart;
unsigned dataend;


unexec( new_name, a_name, data_start, bss_start, entry_address)
     char *new_name, *a_name;
     unsigned data_start, bss_start, entry_address;
{
    FILE *new, *a_out, *core;
    unsigned pagemask;
    /* avoid fclose hazards... */
    char buf0[BUFSIZ];
    char buf1[BUFSIZ];

    pagemask = NBPG -1;

    datastart = DATA_START;
    dataend = ((sbrk(0) + pagemask) &~pagemask);
    if(dataend < datastart){
      fprintf(stderr, "unexec error: data ends before beginning.\n");
      return(-1);
    }
    datacnt = dataend - datastart;
    
    if ((a_out = fopen(a_name, "r")) == NULL)
    {
	perror(a_name);
	exit(1);
    }
    (void) setbuf(a_out, buf0);
    

    if ((new = fopen(new_name, "w")) == NULL)
    {
	perror(new_name);
	exit(1);
    }
    (void) setbuf(a_out, buf1);

    make_hdr(new, a_out, entry_address);
    copy_text(new, a_out);
    copy_data(new);
    fclose(new);

    fclose(a_out);
    mark_x(new_name);
    return(0);
}

/*
 * Make the header in the new a.out from the header in the old one
 * modified by the new data size.
 */
#ifdef hp9000s800
#undef N_BADMAG
#define N_BADMAG(h) (h.a_magic != SHARE_MAGIC)
struct som_exec_auxhdr auxhdr,oauxhdr;
#endif hp9000s800

make_hdr(new, a_out, entry_addr)
@FILE *new, *a_out;
unsigned entry_addr;
{
  if (fread(&hdr, sizeof hdr, 1, a_out) != 1)
    {
      perror("Couldn't read header from a.out file");
      exit(1);
    }
  ohdr = hdr;
  if (fread(&auxhdr, sizeof auxhdr, 1, a_out) != 1)
    {
      perror("Couldn't read auxiliary header from a.out file");
      exit(1);
    }
  oauxhdr = auxhdr;
  printf("Bss  segment size was %u\n", auxhdr.exec_bsize);
  printf("Data segment size was %u", auxhdr.exec_dsize);
  
    /* this is very hackly */
  /* do just enough to make the exec 
     loader happy */
  
  auxhdr.exec_dsize = datacnt;
  auxhdr.exec_bsize = 0;			/* all data is inited now! */
  auxhdr.exec_tfile = roundup(hdr.aux_header_location + hdr.aux_header_size,NBPG);
  auxhdr.exec_dfile = roundup(auxhdr.exec_tfile+auxhdr.exec_tsize,NBPG);
  printf(" now is %u\n", auxhdr.exec_dsize);
  printf("Data segment loc was %u", auxhdr.exec_dmem);
  auxhdr.exec_dmem = datastart;
  printf(" now is %u\n", auxhdr.exec_dmem);
  
  /* entry point unchanged. */
  if (fwrite(&hdr, sizeof hdr, 1, new) != 1)
    {
      perror("Couldn't write header to new a.out file");
      exit(1);
    }
  if (fwrite(&auxhdr, sizeof auxhdr, 1, new) != 1)
    {
      perror("Couldn't write auxiliary header to new a.out file");
      exit(1);
    }
  
}

/*
 * Copy the text from the a.out to the new a.out
 */
copy_text(new, a_out)
     FILE *new, *a_out;
{
  char page[PSIZE];
  int txtcnt = auxhdr.exec_tsize;
  
  if (hdr.a_magic == EXEC_MAGIC)
    {
      printf("a.out file is not shared text, this wont work.\n");
      exit(1);
    }
  fseek(new, auxhdr.exec_tfile, 0);
  fseek(a_out, oauxhdr.exec_tfile, 0);
  while (txtcnt >= PSIZE)
    {
      if (fread(page, PSIZE, 1, a_out) != 1)
	{
	  perror("Read failure on a.out text");
	  exit(1);
	}
      if (fwrite(page, PSIZE, 1, new) != 1)
	{
	  perror("Write failure in text segment");
	  exit(1);
	}
      txtcnt -= PSIZE;
    }
  if (txtcnt)
    {
      if (fread(page, txtcnt, 1, a_out) != 1)
	{
	  perror("Read failure on a.out text");
	  exit(1);
	}
      if (fwrite(page, txtcnt, 1, new) != 1)
	{
	  perror("Write failure in text segment");
	  exit(1);
	}
    }
}

/*
 * copy the data from the core file to the new a.out
 */
copy_data(new)
@FILE *new;
{
  fseek(new,auxhdr.exec_dfile,0);
  if (fwrite(datastart,datacnt,1,new) != 1) {
    perror("Write failure in data segment");
    exit(1);
  }
}

/*
 * After succesfully building the new a.out, mark it executable
 */
mark_x(name)
char *name;
{
    struct stat sbuf;
    int um;

    um = umask(777);
    umask(um);
    if (stat(name, &sbuf) == -1)
    {
	perror ("Can't stat new a.out");
	fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
	sbuf.st_mode = 0777;
    }
    sbuf.st_mode |= 0111 & ~um;
    if (chmod(name, sbuf.st_mode) == -1)
	perror("Couldn't change mode of new a.out to executable");

}
@//E*O*F unexec.s800//

set `wc -lwc <unexec.s800`
if test $1 -ne 217 -o $2 -ne 607 -o $3 -ne 4746
then	echo ! unexec.s800 should have 217 lines, 607 words, and 4746 characters
	echo ! but has $1 lines, $2 words, and $3 characters
fi
chmod 664 unexec.s800

echo "End of shell archive."
exit 0

bd@hpsemc.HP.COM (bob desinger) (03/31/88)

I should mention that I built a minimalist Gnu Emacs: no clash
detection, no X Windows, no HP-UX netunam.  (I didn't try to build
one with those features because I don't need them.)

-- bd