ftp.nice.ch/pub/next/developer/languages/lisp/AKCL.1.599.s.tar.gz#/akcl-1-599/c/unixsave_aix3.c

This is unixsave_aix3.c in view mode; [Download] [Up]

/*
(c) Copyright Taiichi Yuasa and Masami Hagiya, 1984.  All rights reserved.
Copying of this file is authorized to users who have executed the true and
proper "License Agreement for Kyoto Common LISP" with SIGLISP.

(c) Copyright William F. Schelter.
  
*/
/*
	unixsave.c
*/
#ifndef UNIX
#include "include.h"
#endif

#include <fcntl.h>
#include <filehdr.h>
#include <aouthdr.h>
#include <scnhdr.h>
filecpy(to, from, n)
FILE *to, *from;
register int n;
{
	char buffer[BUFSIZ];
	for (;;)
		if (n > BUFSIZ) {
			fread(buffer, BUFSIZ, 1, from);
			fwrite(buffer, BUFSIZ, 1, to);
			n -= BUFSIZ;
		} 
		else if (n > 0) {
			fread(buffer, 1, n, from);
			fwrite(buffer, 1, n, to);
			break;
		} 
		else
			break;
}
#include <sys/ldr.h>
#include <loader.h>
char *__start;
memory_save(original_file, save_file)
char *original_file, *save_file;
{     /*   MEM_SAVE_LOCALS; */ 
    struct filehdr Eheader;
    struct aouthdr header;
    struct scnhdr  shdrs[15];
    int stsize;
    int textsize=0;
    int after_data;
    int orig_data_scnptr;
    int orig_debug_scnptr;

    char *data_begin, *data_end;
    int original_data;
    FILE *original, *save;
    register int n;
    register char *p;
    extern char *sbrk();
    extern char stdin_buf[BUFSIZ], stdout_buf[BUFSIZ];
    fclose(stdin);
    original = fopen(original_file, "r");
    if (stdin != original || original->_file != 0) {
      fprintf(stderr, "Can't open the original file.\n");
      exit(1);
    }
    setbuf(original, stdin_buf);
    fclose(stdout);
    unlink(save_file);
    n = open(save_file, O_CREAT|O_WRONLY, 0777);
    if (n != 1 || (save = fdopen(n, "w")) != stdout) {
      fprintf(stderr, "Can't open the save file.\n");
      exit(1);
    }
    setbuf(save, stdout_buf);
    /*	READ_HEADER; */
    fread(&Eheader, sizeof(Eheader), 1, original);
    fread(&header, sizeof(header), 1, original);
    data_begin= 0x20000800;
    {
      char buf[500];
      struct ld_info * ld;
      loadquery(L_GETINFO,buf,sizeof(buf));
      ld = (struct ld_info *)buf;
      data_begin = ld->ldinfo_dataorg ;
    }

    /* 	header.data_start = data_begin; */

    data_end = core_end;
    original_data = header.dsize;
    header.dsize = data_end - data_begin;
    header.bsize = 0;
    {
      int j,i = Eheader.f_nscns;
      int diff;
      fread(shdrs +1 ,i,sizeof(struct scnhdr),original);
      orig_data_scnptr = shdrs[header.o_sndata].s_scnptr;
      orig_debug_scnptr = shdrs[8].s_scnptr;
      diff = header.a_data - original_data
	- shdrs[header.o_snbss + 1].s_size;
      after_data = shdrs[header.o_snbss +2].s_scnptr;
      Eheader.f_symptr += diff;
      fwrite(&Eheader, sizeof(Eheader), 1, save);
      fwrite(&header, sizeof(header), 1, save);
      shdrs[header.o_snbss ].s_size = 0;
      shdrs[header.o_snbss +1 ].s_size = 0;
      /* ex**pect no more than 15 sections, and pad after data */
      if (strcmp(".pad",shdrs[header.o_snbss + 1].s_name)
	  || i >= 15)
	perror("unexpected format of object file");
      shdrs[header.o_sndata ].s_size = header.a_data;
      /*       shdrs[header.o_sndata].s_paddr = data_begin;
	       shdrs[header.o_sndata].s_vaddr = data_begin;
	       */
      for (j=1; j<= i; j++)
#define ADJUST(x) if(x) (x) = (x) + diff       	 	 	  
	{
	  ADJUST(shdrs[j].s_lnnoptr);
	  ADJUST(shdrs[j].s_relptr);
	}
      for (j= header.o_sndata +1 ; j<= i; j++)
	{
	  ADJUST(shdrs[j].s_scnptr);
	  ADJUST(shdrs[j].s_vaddr);
	  ADJUST(shdrs[j].s_paddr);
	}
      fwrite(shdrs +1  ,i,sizeof(struct scnhdr),save);


      /*	FILECPY_HEADER; */
      filecpy(save, original,
	      shdrs[header.o_sndata].s_scnptr
	      - sizeof(header)-sizeof(Eheader) - i*sizeof(struct scnhdr));

      j= ftell(save);
      j= ftell(original);
      for (n = header.a_data, p = data_begin;  ;  n -= BUFSIZ, p += BUFSIZ)
	if (n > BUFSIZ)
	  fwrite(p, BUFSIZ, 1, save);
	else if (n > 0) {
	  fwrite(p, 1, n, save);
	  break;
	} 
	else
	  break;
      fseek(original, original_data, 1);
      fseek(original, after_data, 0);

      /* now positioned at the loader section */
      {
	struct ldhdr *ldheader;
	struct ldrel * ldreloc_info,*p;
	char *space;
	space = (char *)  sbrk(shdrs[header.o_snloader].s_size + 0x2000);
	ldheader =  (struct ldhdr *) space;
	fread(space,1,shdrs[header.o_snloader].s_size,original);
	ldreloc_info = (struct ldrel *)
	  (space + sizeof(struct ldhdr) + LDSYMSZ * ldheader->l_nsyms);
	i =  sizeof(struct ldhdr) + LDSYMSZ * (ldheader->l_nsyms);
	for(p=ldreloc_info,i=0;  i< ldheader->l_nreloc ; i++,p++)
	  { 
	    if (p->l_rsecnm == header.o_snbss)
	      (p->l_rsecnm = header.o_sndata);
	    if (p->l_symndx == 2) /* make bss be data */
	      (p->l_symndx = 1);
	  }
	/*	     p->l_vaddr += data_begin; */
	fwrite(ldheader, 1, shdrs[header.o_snloader].s_size,save);
	/* unrelocate */
	{
	  int j1 = ftell(save);
	  int j2= ftell(original);
	  int off=0;
	  fseek(original,orig_data_scnptr,0);
	  fseek(save,shdrs[header.o_sndata].s_scnptr,0);
	  for(p=ldreloc_info,i=0;  i< ldheader->l_nreloc ; i++,p++)
	    if (p->l_rsecnm == header.o_sndata)
	      {
		int x,pos1,y;
		int d = p->l_vaddr - off;
		if (d)
		  {
		    fseek(save,d,1);
		    fseek(original,d,1);
		    off += d;
		  }
		pos1 = ftell(original);
		pos1 = ftell(save);
		fread(&x,1,sizeof(int),original);
		y = x;
		if (p->l_symndx ==0)
		  { 
		    int w =  *((int *)&__start);
		    x = ((*(int *)(data_begin+off)));
		    x = x + header.text_start ;
		    x = x - w ;
		  }
		if  (p->l_symndx ==1 || p->l_symndx ==2)
		  {
		    x = ((*(int *)(data_begin + off)) - (int) data_begin);
		  }
		fwrite(&x,1,sizeof(int),save);
		off += sizeof(int);
	      }
	  fseek(save,j1,0);
	  fseek(original,j2,0);

	}
      }

      sbrk(- (shdrs[header.o_snloader].s_size+ 0x2000));
      filecpy(save,original,Eheader.f_symptr - ftell(save));
      /* now at the beginning of the sym table */
      {
	struct syment symbol;
	struct syment *sym = &symbol;
	int naux;
	int nsyms = Eheader.f_nsyms;
	while (--nsyms >= 0)
	  {
	    fread(&symbol,1,SYMESZ,original);
	    fwrite(&symbol,1,SYMESZ,save);
	    naux= sym->n_numaux;
	    nsyms = nsyms - naux;
	    if (ISFCN(sym->n_type)
		&& (naux >= 2))
	      { 
		fread(&symbol,1,SYMESZ,original);
		(((union auxent *)(sym))->x_sym.x_fcnary.x_fcn.x_lnnoptr) += diff;
		fwrite(&symbol,1,SYMESZ,save);
		filecpy(save,original,SYMESZ*(naux -1));
	      }
	    else
	      filecpy(save,original,SYMESZ*(naux));
	  }
      }


      COPY_TO_SAVE;
      fclose(original);
      fclose(save);
    }
  }
Lsave()
{
	char filename[256];
	check_arg(1);
	check_type_or_pathname_string_symbol_stream(&vs_base[0]);
	coerce_to_filename(vs_base[0], filename);
	_cleanup();
	/*
	{
		FILE *p;
		int nfile;
		nfile = NUMBER_OPEN_FILES;
		for (p = &_iob[3];  p < &_iob[nfile];  p++)
			fclose(p);
	}
*/
	memory_save(kcl_self, filename);
	_exit(0);
	/*
	exit(0);
*/
	/*  no return  */
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.