This is saveaix3.c in view mode; [Download] [Up]
/* Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa This file is part of GNU Common Lisp, herein referred to as GCL GCL is free software; you can redistribute it and/or modify it under the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by the Free Software Foundation; either version 2, or (at your option) any later version. GCL 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with GCL; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. (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(); 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.