dclemans@mntgfx.mentor.com (Dave Clemans @ APD x1292) (05/30/89)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 4 (of 4)." # Contents: coff.c # Wrapped by dclemans@dclemans on Mon May 29 13:06:57 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'coff.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'coff.c'\" else echo shar: Extracting \"'coff.c'\" \(53153 characters\) sed "s/^X//" >'coff.c' <<'END_OF_FILE' X/* X * Write out a COFF format file, based on information X * from a GNU format object file. X */ X#include <stdio.h> X#include <string.h> X#include <memory.h> X#include <sys/types.h> X#include <sys/stat.h> Xextern char *malloc(); Xextern char *realloc(); Xextern long time(); Xextern char *getcwd(); X X#include "//dclemans/gnu/src/gcc/version.c" X#define GNU_VERSION "//dclemans/gnu/src/gcc/version.c" X X/* X * C language startup X */ X/* X Apollo C startup stuff; we must add it on our own (if main in file...) X This is what it should look like (from expanded listing) X X 001C: <apollo_c_startup> X 001C:4E560000 LINK SB,#0 X 0020:487A000E PEA ->main X 0024:4EB900000000 JSR <transfer vector> unix_$main X 002A:4E5E UNLK SB X 002C:4E75 RTS X 002E:2048 MOVEA.L A0,A0 X 0030:00000000 AC ->main X*/ Xstatic long c_apollo_start[6] = X{ X 0x4e560000, 0x487a000e, 0x4eb90000, 0x00004e5e, 0x4e752048, 0x00000000 X}; X#define C_RELOC_UNIXMAIN 10 /* point at jsr unix_$main (past jsr word) */ X#define C_RELOC_MAIN 20 /* point at ac main */ X X/* X * C++ language startup X */ X/* X GNU C++ startup stuff for Apollo (& gnu2coff); we must add it on our own (if main in file...) X This is what it looks like: X X We depend on sr10 (or compatible) /usr/lib/crt0.o being linked in X X ** Text section X 00008130 _main: X 00008130 4E56 0000 LINK A6,#0000 X 00008134 2F0D MOVE.L A5,-(A7) X 00008136 2A79 00000000 MOVE.L _GLOBAL_$$HEADER,A5 X 0000813C 4A8D TST.L A5 X 0000813E 6710 BEQ +10 X 00008140 206D 0004 MOVE.L 0004(A5),A0 X 00008144 4A88 TST.L A0 X 00008146 6702 BEQ +02 X 00008148 4E90 JSR (A0) X 0000814A 2A55 MOVE.L (A5),A5 X 0000814C 4A8D TST.L A5 X 0000814E 66F0 BNE +F0 X 00008150 4EB9 00000000 JSR main X 00008156 2A79 00000000 MOVE.L _GLOBAL_$$HEADER,A5 X 0000815C 4A8D TST.L A5 X 0000815E 6710 BEQ +10 X 00008160 206D 0008 MOVE.L 0008(A5),A0 X 00008164 4A88 TST.L A0 X 00008166 6702 BEQ +02 X 00008168 4E90 JSR (A0) X 0000816A 2A55 MOVE.L (A5),A5 X 0000816C 4A8D TST.L A5 X 0000816E 66F0 BNE +F0 X 00008170 2A5F MOVE.L (A7)+,A5 X 00008172 4E5E UNLK A6 X 00008174 4E75 RTS X*/ Xstatic long cc_apollo_start[18] = X{ X 0x4e560000, 0x2f0d2a79, 0x00000000, 0x4a8d6710, 0x206d0004, X 0x4a886702, 0x4e902a55, 0x4a8d66f0, 0x4eb90000, 0x00002a79, X 0x00000000, 0x4a8d6710, 0x206d0008, 0x4a886702, 0x4e902a55, X 0x4a8d66f0, 0x2a5f4e5e, 0x4e750000 X}; X#define CC_RELOC_MAIN 0x22 X#define CC_RELOC_HDR1 0x08 X#define CC_RELOC_HDR2 0x28 X X#define START_SYM "unix_$main" X#define START_CODESYM "<apollo_c_startup>" Xstatic char *apollo_start = (char *)NULL; Xstatic long apollo_start_size = 0; X X#include <a.out.h> X#include <apollo/base.h> X#include <sri.h> X#include <mir.h> Xextern void uid_$gen(); X X#include "gnu2coff.h" X Xextern void coff_text_reloc(); Xextern long coff_def_undef(); X Xstatic struct filehdr *s_filehdr; Xstatic struct aouthdr *s_domainhdr; Xstruct scnhdr *s_text; static char *text_ptr; Xstatic struct scnhdr *s_aptv; static char *aptv_ptr; Xstruct scnhdr *s_data; static char *data_ptr; Xstruct scnhdr *s_bss; Xstatic char *s_syms; static long n_syms; Xstatic char *s_string; static long n_string; Xstatic struct reloc *s_t_reloc; static long n_t_reloc; Xstatic struct reloc tr; Xstatic long text_sym = -STEXT; Xstatic struct reloc *s_d_reloc; static long n_d_reloc; Xstatic struct reloc dr; Xstatic long data_sym = -SDATA; Xstatic long bss_sym = -SBSS; Xstatic struct reloc *s_a_reloc; static long n_a_reloc; Xstatic struct reloc ar; Xstatic long aptv_sym = -SAPTV; Xstatic struct scnhdr *s_sri; static char *sri_recs; static long n_sri_recs; Xstatic struct scnhdr *s_mir; static char *mir_recs; Xstatic struct lineno *s_t_lines; static long n_t_lines; Xstatic char *s_patches; static long n_patches; X Xvoid coff_filehdr() X{ X s_filehdr = (struct filehdr *)malloc(FILHSZ); X if (s_filehdr == (struct filehdr *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for coff filehdr\n"); X exit(1); X } X s_filehdr->f_magic = APOLLOM68KMAGIC; X s_filehdr->f_nscns = 0; /* set later */ X s_filehdr->f_timdat = time(0L); X s_filehdr->f_symptr = 0; /* set later */ X s_filehdr->f_nsyms = 0; /* set later */ X s_filehdr->f_opthdr = sizeof(struct aouthdr); X s_filehdr->f_flags = F_LSYMS; /* corresponds to current version; i.e. most debug stuff not there */ X X s_domainhdr = (struct aouthdr *)malloc(sizeof(struct aouthdr)); X if (s_domainhdr == (struct aouthdr *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for coff domainhdr\n"); X exit(1); X } X s_domainhdr->vformat = APOLLO_COFF_VERSION_NUMBER; X s_domainhdr->vstamp = 0; X s_domainhdr->tsize = 0; /* set later */ X s_domainhdr->dsize = 0; /* set later */ X s_domainhdr->bsize = 0; /* set later */ X s_domainhdr->entry = 0; /* set later */ X s_domainhdr->text_start = 0; /* set later */ X s_domainhdr->data_start = 0; /* set later */ X s_domainhdr->o_sri = 0; /* set later */ X s_domainhdr->o_inlib = 0; X#ifdef never X uid_$gen(s_domainhdr->vid); X#endif X s_domainhdr->vid[0] = 0; X s_domainhdr->vid[1] = 0; X} /* end of coff_filehdr */ X Xvoid coff_text(textptr,size) Xchar *textptr; Xlong size; X{ X register int i; X X s_text = (struct scnhdr *)malloc(SCNHSZ); X if (s_text == (struct scnhdr *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for text header\n"); X exit(1); X } X for (i = 0; i < sizeof s_text->s_name; i++) X s_text->s_name[i] = '\0'; X strcpy(s_text->s_name,_TEXT); X s_text->s_paddr = 0; X s_text->s_vaddr = 0; X s_text->s_size = size; X s_text->s_scnptr = 0; /* set later */ X s_text->s_relptr = 0; /* set later */ X s_text->s_lnnoptr = 0; /* set later */ X s_text->s_nreloc = 0; /* set later */ X s_text->s_nlnno = 0; /* set later */ X s_text->s_flags = STYP_INSTRUCTION|STYP_TEXT; X text_ptr = textptr; X X s_aptv = (struct scnhdr *)malloc(SCNHSZ); X if (s_aptv == (struct scnhdr *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for aptv header\n"); X exit(1); X } X for (i = 0; i < sizeof s_aptv->s_name; i++) X s_aptv->s_name[i] = '\0'; X strcpy(s_aptv->s_name,_APTV); X s_aptv->s_paddr = 0; X s_aptv->s_vaddr = 0; X s_aptv->s_size = 0; X s_aptv->s_scnptr = 0; /* set later */ X s_aptv->s_relptr = 0; /* set later */ X s_aptv->s_lnnoptr = 0; /* set later */ X s_aptv->s_nreloc = 0; /* set later */ X s_aptv->s_nlnno = 0; /* set later */ X s_aptv->s_flags = STYP_DATA; X aptv_ptr = (char *)NULL; X X s_filehdr->f_nscns += 2; X} /* end of coff_text */ X Xvoid coff_data(dataptr,size) Xchar *dataptr; Xlong size; X{ X register int i; X X s_data = (struct scnhdr *)malloc(SCNHSZ); X if (s_data == (struct scnhdr *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for data header\n"); X exit(1); X } X for (i = 0; i < sizeof s_data->s_name; i++) X s_data->s_name[i] = '\0'; X strcpy(s_data->s_name,_DATA); X s_data->s_paddr = 0; X s_data->s_vaddr = 0; X s_data->s_size = size; X s_data->s_scnptr = 0; /* set later */ X s_data->s_relptr = 0; /* set later */ X s_data->s_lnnoptr = 0; /* set later */ X s_data->s_nreloc = 0; /* set later */ X s_data->s_nlnno = 0; /* set later */ X if (size != 0) X s_data->s_flags = STYP_ZERO|STYP_DATA; X else s_data->s_flags = STYP_BSS; X data_ptr = dataptr; X X s_filehdr->f_nscns++; X} /* end of coff_data */ X Xvoid coff_bss(size) Xlong size; X{ X register int i; X X s_bss = (struct scnhdr *)malloc(SCNHSZ); X if (s_bss == (struct scnhdr *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for bss header\n"); X exit(1); X } X for (i = 0; i < sizeof s_bss->s_name; i++) X s_bss->s_name[i] = '\0'; X strcpy(s_bss->s_name,_BSS); X s_bss->s_paddr = 0; X s_bss->s_vaddr = 0; X s_bss->s_size = size; X s_bss->s_scnptr = 0; /* set later */ X s_bss->s_relptr = 0; /* set later */ X s_bss->s_lnnoptr = 0; /* set later */ X s_bss->s_nreloc = 0; /* set later */ X s_bss->s_nlnno = 0; /* set later */ X s_bss->s_flags = STYP_BSS; X X s_filehdr->f_nscns++; X} /* end of coff_bss */ X Xstatic long new_string(string) Xchar *string; X{ X register char *p; X register long newlen; X register long index; X X if (s_string != (char *)NULL) X { /* already in table? */ X for (p = s_string; p < &s_string[n_string]; p++) X { /* look at each piece */ X if (strcmp(string,p) == 0) X { /* found a match? */ X index = (long)(p - s_string); X return index+sizeof n_string; X } X while (*p) X p++; X } X } X X newlen = strlen(string) + 1; X if (n_string == 0) X { /* if no table yet */ X index = 0; X s_string = (char *)malloc(newlen + 1); X if (s_string == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for strings\n"); X exit(1); X } X n_string = newlen + 1; X } X else X { /* bump existing table */ X index = n_string - 1; X s_string = (char *)realloc(s_string,n_string + newlen); X if (s_string == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for strings\n"); X exit(1); X } X n_string += newlen; X } X for (p = &s_string[index]; newlen >= 0; newlen--) X *p++ = '\0'; X strcpy(&s_string[index],string); X return index+sizeof n_string; X} /* end of new_string */ X Xstruct syment *coff_symbol_space(count,number) Xlong count; Xlong *number; X{ X register char *s; X X *number = n_syms; X if (n_syms == 0) X { /* first creation? */ X s_syms = (char *)malloc(count*SYMESZ); X if (s_syms == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for coff symbols\n"); X exit(1); X } X n_syms = count; X } X else X { /* increase space? */ X s_syms = (char *)realloc(s_syms,(n_syms+count)*SYMESZ); X if (s_syms == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for coff symbols\n"); X exit(1); X } X n_syms += count; X } X s = (char *)((long)s_syms + (*number * SYMESZ)); X memset(s,'\0',count * SYMESZ); X return (struct syment *)s; X} /* end of coff_symbol_space */ X Xstruct syment *coff_symbol_addr(symnum) Xlong symnum; X{ X return (struct syment *)((long)s_syms + (symnum * SYMESZ)); X} /* end of coff_symbol_addr */ X Xstatic char *current_path = (char *)NULL; X Xlong coff_def_file(file) Xchar *file; X{ X register long i; X long symnum; X struct syment *s; X union auxent *a; X char buffer[BUFSIZ*2]; X X if (current_path == (char *)NULL) X current_path = getcwd((char *)NULL,BUFSIZ); X if (*file != '/') X { /* pseudo-full path */ X sprintf(buffer,"%s/%s",current_path,file); X file = buffer; X } X X s = coff_symbol_space(2L,&symnum); X a = (union auxent *)((long)s_syms + ((symnum+1) * SYMESZ)); X X strcpy(s->n_name,".file"); X s->n_value = -1; /* fix later */ X s->n_scnum = -2; X s->n_type = T_NULL; X s->n_sclass = C_FILE; X s->n_numaux = 1; X if (strlen(file) <= FILNMLEN) X { /* put in directly */ X strncpy(a->x_file.x_fname,file,FILNMLEN); X } X else X { /* put in string table */ X a->x_file._n_n._n_offset = new_string(file); X a->x_file._n_n._n_zeroes = 0; X } X X for (i = 0; i < symnum; i++) X { /* fix any previous files? */ X s = (struct syment *)((long)s_syms + (i * SYMESZ)); X if (s->n_sclass == C_FILE && s->n_value == -1) X { /* found what we need to fix */ X s->n_value = symnum; X break; X } X i += s->n_numaux; X } X X return symnum; X} /* end of coff_def_file */ X Xlong coff_def_symbol(name,value,type,ext) Xchar *name; Xlong value; Xint type; Xint ext; X{ X register long i; X long symnum,usymnum; X struct syment *s; X union auxent *a; X long *ptr; X X if (ext && *name == '_') X name++; X X if (strncmp("_GLOBAL_$I$",name,11) == 0 || strncmp("_GLOBAL_$D$",name,11) == 0) X { /* set up C++ static constructor/destructor */ X cplusplus_mode = 1; X if (strncmp("_GLOBAL_$I$",name,11) == 0) X cplusplus_ctor = value; X else cplusplus_dtor = value; X } X X s = coff_symbol_space(1L,&symnum); X X if (strlen(name) <= SYMNMLEN) X memccpy(s->n_name,name,'\0',SYMNMLEN); X else X { /* put in string table */ X s->n_zeroes = 0; X s->n_offset = new_string(name); X } X s->n_value = value; X s->n_numaux = 0; X if (ext) X s->n_sclass = C_EXT; /* dummy placeholder */ X else s->n_sclass = C_STAT; /* dummy placeholder */ X s->n_type = T_INT; /* dummy placeholder */ X if (type == STEXT && ext) X s->n_type |= (DT_FCN << N_BTSHFT); X s->n_scnum = type; X if (type == STEXT && strcmp(name,"gcc_compiled.") != 0) X { /* add in aux entry */ X s->n_numaux = 1; X a = (union auxent *)coff_symbol_space(1L,&usymnum); X /* assert that symnum+1==usymnum */ X a->x_sym.x_tagndx = 0; /* what to do here? */ X a->x_sym.x_misc.x_fsize = 0; /* what to do here? */ X a->x_sym.x_fcn.x_lnnoptr = 0; /* what to do here? */ X a->x_sym.x_fcn.x_endndx = 0; /* what to do here? */ X a->x_sym.x_tvndx = 0; X } X X if (strcmp(name,"main") == 0 && cplusplus_main != 1) X { /* then need to add apollo startup code */ X cplusplus_main = 1; X if (type != STEXT) X printf("** main not in text section?\n"); X s_domainhdr->entry = s_text->s_size; X if (!cplusplus_mode) X { /* if just ordinary C stuff */ X apollo_start = (char *)c_apollo_start; X apollo_start_size = sizeof c_apollo_start; X usymnum = coff_def_undef(START_SYM,1); X coff_text_reloc(C_RELOC_MAIN+s_text->s_size,symnum); X coff_text_reloc(C_RELOC_UNIXMAIN+s_text->s_size,usymnum); X } X else X { /* put in our C++ stuff */ X apollo_start = (char *)cc_apollo_start; X apollo_start_size = sizeof cc_apollo_start; X coff_text_reloc(CC_RELOC_MAIN+s_text->s_size,symnum); X coff_text_reloc(CC_RELOC_HDR1+s_text->s_size,-SGLOBAL); X coff_text_reloc(CC_RELOC_HDR2+s_text->s_size,-SGLOBAL); X s = coff_symbol_addr(symnum); X memccpy(s->n_name,"_main",'\0',SYMNMLEN); X (void) coff_def_symbol("main",s_text->s_size,STEXT,1); X ptr = (long *)&apollo_start[CC_RELOC_MAIN]; X *ptr = value; X } X (void) coff_def_symbol(START_CODESYM,s_text->s_size,STEXT,1); X } X X return symnum; X} /* end of coff_def_symbol */ X Xlong coff_def_undef(name,ext) Xchar *name; Xint ext; X{ X register long i; X long symnum; X struct syment *s; X X if (ext && *name == '_') X name++; X X s = coff_symbol_space(1L,&symnum); X X if (strlen(name) <= SYMNMLEN) X memccpy(s->n_name,name,'\0',SYMNMLEN); X else X { /* put in string table */ X s->n_zeroes = 0; X s->n_offset = new_string(name); X } X s->n_scnum = 0; X s->n_value = 0; X s->n_numaux = 0; X if (ext) X s->n_sclass = C_EXT; /* dummy placeholder */ X else s->n_sclass = C_STAT; /* dummy placeholder */ X s->n_type = T_INT | (DT_FCN << N_BTSHFT); X X return symnum; X} /* end of coff_def_undef */ X Xlong coff_def_section(num,addr,size,nreloc,nline) Xint num; Xlong addr; Xlong size; Xint nreloc; Xint nline; X{ X register long i; X long symnum; X struct syment *s; X union auxent *a; X char *name; X X switch (num) X { /* what name? */ X case STEXT: X name = _TEXT; X break; X case SAPTV: X name = _APTV; X break; X case SDATA: X name = _DATA; X break; X case SBSS: X name = _BSS; X break; X case SSRI: X name =_SRI; X break; X case SMIR: X name =_MIR; X break; X default: X fprintf(stderr,"gnu2coff: logic error in coff_def_section!\n"); X exit(1); X } X if (s_data == (struct scnhdr *)NULL && num == SDATA) X { /* conflict? */ X fprintf(stderr,"gnu2coff: logic error in coff_def_section!\n"); X exit(1); X } X if (s_bss == (struct scnhdr *)NULL && num == SBSS) X { /* conflict? */ X fprintf(stderr,"gnu2coff: logic error in coff_def_section!\n"); X exit(1); X } X X s = coff_symbol_space(2L,&symnum); X a = (union auxent *)((long)s_syms + ((symnum+1) * SYMESZ)); X X if (strlen(name) <= SYMNMLEN) X memccpy(s->n_name,name,'\0',SYMNMLEN); X else X { /* put in string table */ X s->n_zeroes = 0; X s->n_offset = new_string(name); X } X s->n_scnum = num; X s->n_value = addr; X s->n_numaux = 1; X s->n_sclass = C_STAT; X s->n_type = T_NULL; X a->x_scn.x_scnlen = size; X a->x_scn.x_nreloc = nreloc; X a->x_scn.x_nlinno = nline; X X switch (num) X { /* save symbol pointers */ X case STEXT: X text_sym = symnum; X break; X case SDATA: X data_sym = symnum; X break; X case SAPTV: X aptv_sym = symnum; X break; X case SBSS: X bss_sym = symnum; X break; X } X X return symnum; X} /* end of coff_def_section */ X Xvoid coff_aptv_reloc(vaddr,symnum) Xlong vaddr; Xlong symnum; X{ X long aentry; X struct reloc *r; X X if (n_a_reloc == 0) X { /* create first entry? */ X aentry = 0; X s_a_reloc = (struct reloc *)malloc(RELSZ); X if (s_a_reloc == (struct reloc *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for aptv reloc entries\n"); X exit(1); X } X n_a_reloc = 1; X } X else X { /* bump existing stuff */ X aentry = n_a_reloc; X s_a_reloc = (struct reloc *)realloc(s_a_reloc,(n_a_reloc+1)*RELSZ); X if (s_a_reloc == (struct reloc *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for aptv reloc entries\n"); X exit(1); X } X n_a_reloc++; X } X r = (struct reloc *)((long)s_a_reloc + (aentry * RELSZ)); X X r->r_vaddr = vaddr; X r->r_symndx = symnum; X r->r_type = R_DIR32; X X if (s_aptv->s_nreloc != S_NRELOC_ESC) X s_aptv->s_nreloc++; X if (s_aptv->s_nreloc == 0) X { /* if it overflowed */ X s_aptv->s_nreloc = S_NRELOC_ESC; X ar.r_vaddr = n_a_reloc; X ar.r_symndx = 0; X ar.r_type = R_NRELOC; X } X if (ar.r_vaddr != 0) X ar.r_vaddr = n_a_reloc; X} /* end of coff_aptv_reloc */ X Xlong coff_aptv_entry(symnum) Xlong symnum; X{ X long vaddr; X long *word; X short *instr; X X if (s_aptv->s_size == 0) X { /* if first entry */ X aptv_ptr = (char *)malloc(sizeof(short)+sizeof(long)); X if (aptv_ptr == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for aptv entries\n"); X exit(1); X } X } X else X { /* bump existing stuff */ X aptv_ptr = (char *)realloc(aptv_ptr,s_aptv->s_size+sizeof(short)+sizeof(long)); X if (aptv_ptr == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for aptv entries\n"); X exit(1); X } X } X instr = (short *)&aptv_ptr[s_aptv->s_size]; X *instr = JUMP_INSTR; X word = (long *)&aptv_ptr[s_aptv->s_size+sizeof(short)]; X *word = 0; X vaddr = s_aptv->s_size; X s_aptv->s_size += sizeof(short)+sizeof(long); X return vaddr; X} /* end of coff_aptv_entry */ X Xlong coff_patch_space(length,memaddr) Xlong length; Xchar **memaddr; X{ X long vaddr; X long newlen; X char *ptr; X long *word; X short *instr; X X if (s_data == (struct scnhdr *)NULL) X coff_data((char *)NULL,0); X X vaddr = n_patches; X newlen = ((n_patches + length + sizeof(long) - 1) / sizeof(long)) * sizeof(long); X if (n_patches == 0) X { /* if first alloc */ X s_patches = (char *)malloc(newlen); X if (s_patches == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for data patches\n"); X exit(1); X } X } X else X { /* bump existing size */ X s_patches = (char *)realloc(s_patches,newlen); X if (s_patches == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for data patches\n"); X exit(1); X } X } X n_patches = newlen; X *memaddr = &s_patches[vaddr]; X return vaddr; X} /* end of coff_patch_space */ X Xvoid coff_text_reloc(vaddr,symnum) Xlong vaddr; Xlong symnum; X{ X long tentry; X struct reloc *r,*nr; X struct syment *s; X long *word; X short *instr; X char *name; X X if (n_t_reloc == 0) X { /* create first entry? */ X tentry = 0; X s_t_reloc = (struct reloc *)malloc(RELSZ); X if (s_t_reloc == (struct reloc *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for text reloc entries\n"); X exit(1); X } X n_t_reloc = 1; X } X else X { /* bump existing stuff */ X tentry = n_t_reloc; X s_t_reloc = (struct reloc *)realloc(s_t_reloc,(n_t_reloc+1)*RELSZ); X if (s_t_reloc == (struct reloc *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for text reloc entries\n"); X exit(1); X } X n_t_reloc++; X } X r = (struct reloc *)((long)s_t_reloc + (tentry * RELSZ)); X X r->r_vaddr = vaddr; X r->r_symndx = symnum; X r->r_type = R_DIR32; X X if (s_text->s_nreloc != S_NRELOC_ESC) X s_text->s_nreloc++; X if (s_text->s_nreloc == 0) X { /* if it overflowed */ X s_text->s_nreloc = S_NRELOC_ESC; X tr.r_vaddr = n_t_reloc; X tr.r_symndx = 0; X tr.r_type = R_NRELOC; X } X if (tr.r_vaddr != 0) X tr.r_vaddr = n_t_reloc; X X if (vaddr < s_text->s_size) X word = (long *)&text_ptr[vaddr]; X else word = (long *)((long)apollo_start + vaddr - s_text->s_size); X s = (struct syment *)((long)s_syms + (symnum * SYMESZ)); X if (symnum >= 0) X { /* if a good symbol pointer */ X if (s->n_zeroes == 0) X name = &s_string[s->n_offset - sizeof n_string]; X else name = s->n_name; X ref_undefined(name,(char *)word,r,s,s_a_reloc,n_a_reloc); X } X} /* end of coff_text_reloc */ X Xvoid coff_data_reloc(vaddr,symnum) Xlong vaddr; Xlong symnum; X{ X long dentry; X struct reloc *r; X X if (s_data == (struct scnhdr *)NULL) X printf("** data relocation without data section\n"); X X if (n_d_reloc == 0) X { /* create first entry? */ X dentry = 0; X s_d_reloc = (struct reloc *)malloc(RELSZ); X if (s_d_reloc == (struct reloc *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for data reloc entries\n"); X exit(1); X } X n_d_reloc = 1; X } X else X { /* bump existing stuff */ X dentry = n_d_reloc; X s_d_reloc = (struct reloc *)realloc(s_d_reloc,(n_d_reloc+1)*RELSZ); X if (s_d_reloc == (struct reloc *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for data reloc entries\n"); X exit(1); X } X n_d_reloc++; X } X r = (struct reloc *)((long)s_d_reloc + (dentry * RELSZ)); X X r->r_vaddr = vaddr; X r->r_symndx = symnum; X r->r_type = R_DIR32; X X if (s_data != (struct scnhdr *)NULL && s_data->s_nreloc != S_NRELOC_ESC) X s_data->s_nreloc++; X if (s_data != (struct scnhdr *)NULL && s_data->s_nreloc == 0) X { /* if it overflowed */ X s_data->s_nreloc = S_NRELOC_ESC; X dr.r_vaddr = n_d_reloc; X dr.r_symndx = 0; X dr.r_type = R_NRELOC; X } X if (dr.r_vaddr != 0) X dr.r_vaddr = n_d_reloc; X} /* end of coff_data_reloc */ X X/* X * What resources does this code need? X * Apollo magic... X */ Xvoid coff_def_sri() X{ X register int i; X srihdr *sh; X srirec *sr; X X s_sri = (struct scnhdr *)malloc(SCNHSZ); X if (s_sri == (struct scnhdr *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for sri header\n"); X exit(1); X } X for (i = 0; i < sizeof s_sri->s_name; i++) X s_sri->s_name[i] = '\0'; X strcpy(s_sri->s_name,_SRI); X s_sri->s_paddr = 0; X s_sri->s_vaddr = 0; X s_sri->s_scnptr = 0; /* set later */ X s_sri->s_relptr = 0; X s_sri->s_lnnoptr = 0; X s_sri->s_nreloc = 0; X s_sri->s_nlnno = 0; X s_sri->s_flags = STYP_INFO; X X n_sri_recs = 6; X s_sri->s_size = (n_sri_recs*SRIRECSZ)+SRIHDRSZ; X sri_recs = (char *)malloc(s_sri->s_size); X if (sri_recs == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for sri recs\n"); X exit(1); X } X sh = (srihdr *)sri_recs; X sr = (srirec *)&sri_recs[SRIHDRSZ]; X sh->nsris = 6; X sr[0].kind = software_sri_kind; X sr[0].combine = take_or_rule; X sr[0].info.value = xrs_software_flag; X sr[1].kind = software_sri_kind; X sr[1].combine = take_or_rule; X sr[1].info.value = reg_save_software_flag; X sr[2].kind = systype_sri_kind; X sr[2].combine = take_special_rule; X sr[2].info.value = 2; /* is this sys5? where does this value come from? */ X sr[3].kind = runtype_sri_kind; X sr[3].combine = take_special_rule; X sr[3].info.value = 2; /* is this sys5? where does this value come from? */ X sr[4].kind = stacksize_sri_kind; X sr[4].combine = take_max_rule; X sr[4].info.value = gen_stack_size; /* 512K stack space (at least) */ X sr[5].kind = hardware_sri_kind; /* 68020+/68881+ hardware */ X sr[5].combine = take_or_rule; X sr[5].info.value = m020_hardware_flag|m881_hardware_flag; X X s_filehdr->f_nscns++; X} /* end of coff_def_sri */ X X/* X * What tool built this code? X * Apollo magic... X */ Xvoid coff_def_mir(module) Xchar *module; X{ X register int i; X mirhdr *mh; X mir *mr; X char buffer[BUFSIZ]; X char mname[BUFSIZ]; X struct stat statb; X X s_mir = (struct scnhdr *)malloc(SCNHSZ); X if (s_mir == (struct scnhdr *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for mir header\n"); X exit(1); X } X for (i = 0; i < sizeof s_mir->s_name; i++) X s_mir->s_name[i] = '\0'; X strcpy(s_mir->s_name,_MIR); X s_mir->s_paddr = 0; X s_mir->s_vaddr = 0; X s_mir->s_scnptr = 0; /* set later */ X s_mir->s_relptr = 0; X s_mir->s_lnnoptr = 0; X s_mir->s_nreloc = 0; X s_mir->s_nlnno = 0; X s_mir->s_flags = STYP_INFO; X X sprintf(buffer,"GNU C System Version %s",version_string); X strcpy(mname,module); X if (mname[strlen(mname)-2] == '.' && mname[strlen(mname)-1] == 'o') X mname[strlen(mname)-2] = '\0'; X X#define MIR_MAKER_SIZE 14 X#define MIR_MODULE_NAME_SIZE 8 X s_mir->s_size = MIRHDRSZ + MIR_MAKER_SIZE + MIR_MODULE_NAME_SIZE; X mir_recs = (char *)malloc(s_mir->s_size); X if (mir_recs == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for mir recs\n"); X exit(1); X } X mh = (mirhdr *)mir_recs; X mh->nmirs = 2; X mr = (mir *)&mir_recs[MIRHDRSZ]; X mr->kind = maker_mir_kind; X mr->mir_size = MIR_MAKER_SIZE; X mr->info.mir_maker.version = 0; X stat(GNU_VERSION,&statb); X mr->info.mir_maker.creation_time = statb.st_mtime; X mr->info.mir_maker.maker_name_offset = new_string(buffer); X mr = (mir *)&mir_recs[MIRHDRSZ + MIR_MAKER_SIZE]; X mr->kind = module_name_mir_kind; X mr->mir_size = MIR_MODULE_NAME_SIZE; X mr->info.mir_module_name.module_name_offset = new_string(mname); X X s_filehdr->f_nscns++; X} /* end of coff_def_mir */ X Xlong coff_text_line(addr,line) Xlong addr; Xshort line; X{ X register long lentry; X register struct lineno *l; X X lentry = n_t_lines; X if (n_t_lines == 0) X { /* if nothing yet */ X s_t_lines = (struct lineno *)malloc(LINESZ); X if (s_t_lines == (struct lineno *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for text line numbers\n"); X exit(1); X } X n_t_lines = 1; X } X else X { /* bump existing stuff */ X s_t_lines = (struct lineno *)realloc(s_t_lines,(n_t_lines+1)*LINESZ); X if (s_t_lines == (struct lineno *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for text line numbers\n"); X exit(1); X } X n_t_lines++; X } X l = (struct lineno *)((long)s_t_lines + (lentry * LINESZ)); X l->l_addr.l_paddr = addr; X l->l_lnno = line; X return lentry; X} /* end of coff_text_line */ X Xstatic void coff_patch_reloc() X{ X register long i; X register struct reloc *r; X X for (i = 0; i < n_t_reloc; i++) X { /* patch pre-built section symbol refs */ X r = (struct reloc *)((long)s_t_reloc + (i * RELSZ)); X switch (r->r_symndx) X { /* anything need patching? */ X case -STEXT: X r->r_symndx = text_sym; X break; X case -SDATA: X if (s_data == (struct scnhdr *)NULL) X printf("** data reference in text relocation without data section\n"); X r->r_symndx = data_sym; X break; X case -SBSS: X if (s_bss == (struct scnhdr *)NULL) X printf("** bss reference in text relocation without bss section\n"); X r->r_symndx = bss_sym; X break; X case -SAPTV: X r->r_symndx = aptv_sym; X break; X case -SGLOBAL: X r->r_symndx = cplusplus_gsym; X break; X } X } X for (i = 0; i < n_a_reloc; i++) X { /* patch pre-built section symbol refs */ X r = (struct reloc *)((long)s_a_reloc + (i * RELSZ)); X switch (r->r_symndx) X { /* anything need patching? */ X case -STEXT: X r->r_symndx = text_sym; X break; X case -SDATA: X if (s_data == (struct scnhdr *)NULL) X printf("** data reference in aptv relocation without data section\n"); X r->r_symndx = data_sym; X break; X case -SBSS: X if (s_bss == (struct scnhdr *)NULL) X printf("** bss reference in aptv relocation without bss section\n"); X r->r_symndx = bss_sym; X break; X case -SAPTV: X r->r_symndx = aptv_sym; X break; X } X } X for (i = 0; i < n_d_reloc; i++) X { /* patch pre-built section symbol refs */ X r = (struct reloc *)((long)s_d_reloc + (i * RELSZ)); X switch (r->r_symndx) X { /* anything need patching? */ X case -STEXT: X r->r_symndx = text_sym; X break; X case -SDATA: X if (s_data == (struct scnhdr *)NULL) X printf("** data reference in data relocation without data section\n"); X r->r_symndx = data_sym; X break; X case -SBSS: X if (s_bss == (struct scnhdr *)NULL) X printf("** bss reference in data relocation without bss section\n"); X r->r_symndx = bss_sym; X break; X case -SAPTV: X r->r_symndx = aptv_sym; X break; X } X } X} /* end of coff_patch_reloc */ X Xstatic void coff_patch_syms() X{ X register long i; X union auxent *a; X struct syment *s; X long scnmap[6]; X struct syment *last_funcs; X union auxent *last_func,*last_bf; X X /* patch section numbers in symbols */ X scnmap[STEXT-1] = i = 1; X if (s_data != (struct scnhdr *)NULL) X scnmap[SDATA-1] = ++i; X scnmap[SAPTV-1] = ++i; X if (s_bss != (struct scnhdr *)NULL) X scnmap[SBSS-1] = ++i; X scnmap[SSRI-1] = ++i; X scnmap[SMIR-1] = ++i; X for (i = 0; i < n_syms; i++) X { /* for each symbol */ X s = (struct syment *)((long)s_syms + (i * SYMESZ)); X if (s->n_scnum > 0) X s->n_scnum = scnmap[s->n_scnum-1]; X i += s->n_numaux; X } X X /* patch chained symtab symbols */ X last_func = last_bf = (union auxent *)NULL; X last_funcs = (struct syment *)NULL; X for (i = 0; i < n_syms; i++) X { /* make symtab entries correct */ X s = (struct syment *)((long)s_syms + (i * SYMESZ)); X a = (union auxent *)((long)s_syms + ((i+1) * SYMESZ)); X if (s->n_sclass == C_FILE && s->n_value == -1) X { /* found what we need to fix */ X s->n_value = n_syms-1; X } X else if (s->n_sclass == C_FCN) X { /* found a function thingy */ X if (strcmp(s->n_name,".bf") != 0 && strcmp(s->n_name,".ef") != 0) X { /* if not a function body */ X a->x_sym.x_fcnary.x_fcn.x_lnnoptr = s_text->s_lnnoptr + X (a->x_sym.x_fcnary.x_fcn.x_lnnoptr * LINESZ); X if (last_func != (union auxent *)NULL) X { /* we can finish the record */ X last_func->x_sym.x_misc.x_fsize = s->n_value - last_funcs->n_value; X last_func->x_sym.x_fcnary.x_fcn.x_endndx = i; X last_funcs->n_sclass = last_func->x_sym.x_tvndx; X last_func->x_sym.x_tvndx = 0; X } X last_funcs = s; X last_func = a; X } X else if (strcmp(s->n_name,".bf") == 0) X { /* do stuff for body */ X if (last_bf != (union auxent *)NULL) X last_bf->x_sym.x_fcnary.x_fcn.x_endndx = i; X last_bf = a; X } X else X { /* do stuff for function end */ X /* nothing needed so far */ X } X } X else if (s->n_scnum == 0) X s->n_type = T_NULL; X i += s->n_numaux; X } X if (last_func != (union auxent *)NULL) X { /* finish out last function */ X last_func->x_sym.x_misc.x_fsize = s_text->s_size - last_funcs->n_value; X last_func->x_sym.x_fcnary.x_fcn.x_endndx = n_syms-1; X last_funcs->n_sclass = last_func->x_sym.x_tvndx; X last_func->x_sym.x_tvndx = 0; X } X if (last_bf != (union auxent *)NULL) X last_bf->x_sym.x_fcnary.x_fcn.x_endndx = n_syms-1; X X /* patch section header symbols */ X/* s = (struct syment *)((long)s_syms + (text_sym * SYMESZ)); */ X a = (union auxent *)((long)s_syms + ((text_sym+1) * SYMESZ)); X a->x_scn.x_scnlen += apollo_start_size; X if (n_t_reloc > 0) X a->x_scn.x_nreloc = s_text->s_nreloc; X if (n_t_lines > 0) X a->x_scn.x_nlinno = n_t_lines; X X s = (struct syment *)((long)s_syms + (aptv_sym * SYMESZ)); X a = (union auxent *)((long)s_syms + ((aptv_sym+1) * SYMESZ)); X s->n_value = s_text->s_size + apollo_start_size; X if (s_data != (struct scnhdr *)NULL) X s->n_value += s_data->s_size + n_patches; X a->x_scn.x_scnlen = s_aptv->s_size; X if (n_a_reloc > 0) X a->x_scn.x_nreloc = s_aptv->s_nreloc; X X s = (struct syment *)((long)s_syms + (data_sym * SYMESZ)); X a = (union auxent *)((long)s_syms + ((data_sym+1) * SYMESZ)); X if (s_data != (struct scnhdr *)NULL) X { /* if a data section */ X s->n_value = s_text->s_size + apollo_start_size; X a->x_scn.x_scnlen = s_data->s_size + n_patches; X if (n_d_reloc > 0) X a->x_scn.x_nreloc = s_data->s_nreloc; X } X X s = (struct syment *)((long)s_syms + (bss_sym * SYMESZ)); X/* a = (union auxent *)((long)s_syms + ((bss_sym+1) * SYMESZ)); */ X if (s_bss != (struct scnhdr *)NULL) X s->n_value = s_text->s_size + apollo_start_size + X (s_data != (struct scnhdr *)NULL) ? s_data->s_size : 0 + n_patches + s_aptv->s_size; X} /* end of coff_patch_syms */ X Xstatic void coff_patch_sections() X{ X register long fileptr; X X fileptr = FILHSZ + sizeof(struct aouthdr) + (s_filehdr->f_nscns * SCNHSZ); X X s_text->s_scnptr = fileptr; X fileptr += s_text->s_size + apollo_start_size; X if (s_data != (struct scnhdr *)NULL) X { /* if a data section */ X s_data->s_scnptr = fileptr; X fileptr += s_data->s_size + n_patches; X } X s_aptv->s_scnptr = fileptr; X fileptr += s_aptv->s_size; X s_sri->s_scnptr = fileptr; X fileptr += s_sri->s_size; X s_mir->s_scnptr = fileptr; X fileptr += s_mir->s_size; X if (n_t_reloc > 0) X { /* set up text reloc */ X s_text->s_relptr = fileptr; X fileptr += n_t_reloc * RELSZ; X } X if (n_d_reloc > 0) X { /* set up data reloc */ X if (s_data != (struct scnhdr *)NULL) X { /* if a data section really exists */ X s_data->s_relptr = fileptr; X fileptr += n_d_reloc * RELSZ; X } X } X if (n_a_reloc > 0) X { /* set up aptv reloc */ X s_aptv->s_relptr = fileptr; X fileptr += n_a_reloc * RELSZ; X } X if (n_t_lines > 0) X { /* set up text lines */ X s_text->s_nlnno = n_t_lines; X s_text->s_lnnoptr = fileptr; X fileptr += n_t_lines * LINESZ; X } X X if (s_bss != (struct scnhdr *)NULL) X s_bss->s_size = ((s_bss->s_size + sizeof(long) - 1) / sizeof(long)) * sizeof(long); X X /* finally, point at the symbol table */ X s_filehdr->f_symptr = fileptr; X s_filehdr->f_nsyms = n_syms; X} /* end of coff_patch_sections */ X Xstatic void coff_remap_file() X{ X register long i; X register struct reloc *r; X register struct syment *s; X struct lineno *lp; X long text,data; X long ptr; X long *word; X X /* very apollo specific magic; in fact this whole function is apollo magic */ X text = 0x8000; X data = text + 0x8000; X while ((text + s_text->s_size + apollo_start_size) > data) X data += 0x8000; X X if (s_domainhdr->entry != 0) X s_domainhdr->entry += text + s_text->s_scnptr; X s_domainhdr->text_start = text; X s_domainhdr->data_start = data; X s_domainhdr->o_sri += text; X X s_text->s_paddr = s_text->s_vaddr = text + s_text->s_scnptr; X ptr = data; X if (s_data != (struct scnhdr *)NULL) X { /* if a data section */ X s_data->s_paddr = s_data->s_vaddr = ptr; X ptr += s_data->s_size + n_patches; X } X s_aptv->s_paddr = s_aptv->s_vaddr = ptr; X ptr += s_aptv->s_size; X if (s_bss != (struct scnhdr *)NULL) X { /* if a bss section */ X s_bss->s_paddr = s_bss->s_vaddr = ptr; X/* ptr += s_bss->s_size; */ X } X X for (i = 0; i < n_syms; i++) X { /* fix the symbol table */ X s = (struct syment *)((long)s_syms + (i * SYMESZ)); X /* if (s->n_type != T_NULL) */ switch (s->n_scnum) X { /* a symbol that needs fixing? */ X case STEXT: X s->n_value += s_text->s_vaddr; X break; X case SAPTV: X s->n_value += s_aptv->s_vaddr; X break; X case SDATA: X if (s_data == (struct scnhdr *)NULL) X break; X s->n_value += s_data->s_vaddr - s_text->s_size; X break; X case SBSS: X#ifdef never X if (s_bss == (struct scnhdr *)NULL) X break; X s->n_value += s_bss->s_vaddr; X#endif X break; X } X i += s->n_numaux; X } X s = (struct syment *)((long)s_syms + (text_sym * SYMESZ)); X s->n_value = s_text->s_vaddr; X s = (struct syment *)((long)s_syms + (aptv_sym * SYMESZ)); X s->n_value = s_aptv->s_vaddr; X s = (struct syment *)((long)s_syms + (data_sym * SYMESZ)); X if (s_data != (struct scnhdr *)NULL) X s->n_value = s_data->s_vaddr; X s = (struct syment *)((long)s_syms + (bss_sym * SYMESZ)); X if (s_bss != (struct scnhdr *)NULL) X s->n_value = s_bss->s_vaddr; X X for (i = 0; i < n_t_reloc; i++) X { /* text relocations */ X r = (struct reloc *)((long)s_t_reloc + (i * RELSZ)); X if (r->r_vaddr < s_text->s_size) X word = (long *)&text_ptr[r->r_vaddr]; X else word = (long *)((long)apollo_start + (r->r_vaddr - s_text->s_size)); X s = (struct syment *)((long)s_syms + (r->r_symndx * SYMESZ)); X if (r->r_symndx == text_sym) X *word += s_text->s_vaddr; X else if (r->r_symndx == aptv_sym) X *word += s_aptv->s_vaddr; X else if (r->r_symndx == data_sym && s_data != (struct scnhdr *)NULL) X *word += s_data->s_vaddr - s_text->s_size; X else if (r->r_symndx == bss_sym && s_bss != (struct scnhdr *)NULL) X *word += s_bss->s_vaddr - s_text->s_size - (s_data != (struct scnhdr *)NULL ? s_data->s_size : 0); X else if (cplusplus_mode && r->r_symndx == cplusplus_gsym) X *word = s->n_value; X else switch (s->n_scnum) X { /* fix based on type */ X case STEXT: X *word += s_text->s_vaddr; X break; X case SAPTV: X *word += s_aptv->s_vaddr; X break; X case SDATA: X *word += s_data->s_vaddr - s_text->s_size; X break; X case SBSS: X *word += s_bss->s_vaddr - s_text->s_size - s_data->s_size; X break; X } X r->r_vaddr += s_text->s_vaddr; X if (r->r_vaddr < s_text->s_vaddr || r->r_vaddr >= (s_text->s_vaddr + s_text->s_size + apollo_start_size)) X printf("** bad text relocation: %d: 0x%08x\n",i,r->r_vaddr); X } X for (i = 0; i < n_a_reloc; i++) X { /* aptv relocations */ X r = (struct reloc *)((long)s_a_reloc + (i * RELSZ)); X r->r_vaddr += s_aptv->s_vaddr; X if (r->r_vaddr < s_aptv->s_vaddr || r->r_vaddr >= (s_aptv->s_vaddr + s_aptv->s_size)) X printf("** bad aptv relocation: %d: 0x%08x\n",i,r->r_vaddr); X } X if (s_data != (struct scnhdr *)NULL) for (i = 0; i < n_d_reloc; i++) X { /* data relocations */ X r = (struct reloc *)((long)s_d_reloc + (i * RELSZ)); X if (r->r_vaddr < s_data->s_size) X word = (long *)&data_ptr[r->r_vaddr]; X else word = (long *)&s_patches[r->r_vaddr - s_data->s_size]; X s = (struct syment *)((long)s_syms + (r->r_symndx * SYMESZ)); X if (r->r_symndx == text_sym && s_text != (struct scnhdr *)NULL) X *word += s_text->s_vaddr; X else if (r->r_symndx == data_sym && s_data != (struct scnhdr *)NULL) X *word += s_data->s_vaddr - s_text->s_size; X else if (r->r_symndx == bss_sym && s_bss != (struct scnhdr *)NULL) X *word += s_bss->s_vaddr - s_text->s_size - (s_data != (struct scnhdr *)NULL ? s_data->s_size : 0); X else switch (s->n_scnum) X { /* fix based on type */ X case STEXT: X *word += s_text->s_vaddr; X break; X case SAPTV: X *word += s_aptv->s_vaddr; X break; X case SDATA: X *word += s_data->s_vaddr - s_text->s_size; X break; X case SBSS: X *word += s_bss->s_vaddr - s_text->s_size - s_data->s_size; X break; X } X r->r_vaddr += s_data->s_vaddr; X if (r->r_vaddr < s_data->s_vaddr || r->r_vaddr >= (s_data->s_vaddr + s_data->s_size + n_patches)) X printf("** bad data relocation: %d: 0x%08x\n",i,r->r_vaddr); X } X X for (i = 0; i < n_t_lines; i++) X { /* adjust line number pointers */ X lp = (struct lineno *)((long)s_t_lines + (i * LINESZ)); X if (lp->l_lnno == 0) X continue; X lp->l_addr.l_paddr += s_text->s_vaddr; X } X} /* end of coff_remap_file */ X Xvoid coff_finish() /* finish off in-memory representation */ X{ X long aptv_size; X long *word; X long relptr; X X relptr = 0; X (void) coff_def_section(STEXT,relptr,s_text->s_size,n_t_reloc,0/* line numbers? */); X relptr += s_text->s_size; X if (s_data != (struct scnhdr *)NULL) X { /* if a data section */ X (void) coff_def_section(SDATA,relptr,s_data->s_size,n_d_reloc,0/* line numbers? */); X relptr += s_data->s_size + n_patches; X } X (void) coff_def_section(SAPTV,relptr,s_aptv->s_size,n_a_reloc,0); X relptr += s_aptv->s_size; X if (s_bss != (struct scnhdr *)NULL) X { /* if a bss section */ X (void) coff_def_section(SBSS,relptr,s_bss->s_size,0,0/* line numbers? */); X/* relptr += s_bss->size; */ X } X#ifdef never X (void) coff_def_section(SSRI,0,s_sri->s_size,0,0); X (void) coff_def_section(SMIR,0,s_mir->s_size,0,0); X#endif X X if (tr.r_vaddr != 0) X n_t_reloc++; X if (dr.r_vaddr != 0) X n_d_reloc++; X if (ar.r_vaddr != 0) X n_a_reloc++; X aptv_size = s_aptv->s_size; X if (s_aptv->s_size % sizeof(long) != 0) X s_aptv->s_size += sizeof(short); X X if (n_t_lines == 0) X s_filehdr->f_flags |= F_LNNO; X X /* do not change the order of the following three calls */ X coff_patch_sections(); X coff_patch_syms(); X coff_patch_reloc(); X X s_domainhdr->tsize = s_text->s_size + apollo_start_size; X if (s_data != (struct scnhdr *)NULL) X s_domainhdr->dsize = s_data->s_size + n_patches; X if (s_bss != (struct scnhdr *)NULL) X s_domainhdr->bsize = s_bss->s_size; X s_domainhdr->data_start = s_domainhdr->tsize + s_aptv->s_size; X s_domainhdr->o_sri = s_sri->s_scnptr; X X coff_remap_file(); X X if (tr.r_vaddr != 0) X n_t_reloc--; X if (dr.r_vaddr != 0) X n_d_reloc--; X if (ar.r_vaddr != 0) X n_a_reloc--; X s_aptv->s_size = aptv_size; X X if (show_coff_code) X { /* disassemble what we just built? */ X disasm("Text section",text_ptr,s_text->s_size,s_text->s_vaddr); X if (apollo_start_size != 0) X disasm("Apollo startup code",apollo_start,apollo_start_size,s_text->s_vaddr+s_text->s_size); X if (n_patches > 0) X disasm("Data relocation patches",s_patches,n_patches,s_data->s_vaddr+s_data->s_size); X if (s_aptv->s_size > 0) X disasm("APTV section",aptv_ptr,s_aptv->s_size,s_aptv->s_vaddr); X } X} /* end of coff_finish */ X Xvoid coff_write(file) Xchar *file; X{ X char buffer[BUFSIZ]; X register char *p; X FILE *fp; X long aptv_size; X short zero = 0; X X p = strrchr(file,'.'); X if (p == (char *)NULL) X { /* if no dots */ X sprintf(buffer,"%s_coff",file); X } X else X { /* more complex name */ X strncpy(buffer,file,(int)(p-file)); X buffer[(int)(p-file)] = '\0'; X strcat(buffer,"_coff"); X strcat(buffer,p); X } X unlink(buffer); X fp = fopen(buffer,"w"); X if (fp == (FILE *)NULL) X { /* got the file? */ X fprintf(stderr,"gnu2coff: unable to create %s\n",buffer); X exit(1); X } X X aptv_size = s_aptv->s_size; X if (s_aptv->s_size % sizeof(long) != 0) X s_aptv->s_size += sizeof(short); X s_text->s_size += apollo_start_size; X if (s_data != (struct scnhdr *)NULL) X s_data->s_size += n_patches; X X fwrite(s_filehdr,FILHSZ,1,fp); X fwrite(s_domainhdr,sizeof (struct aouthdr),1,fp); X fwrite(s_text,SCNHSZ,1,fp); X if (s_data != (struct scnhdr *)NULL) X fwrite(s_data,SCNHSZ,1,fp); X fwrite(s_aptv,SCNHSZ,1,fp); X if (s_bss != (struct scnhdr *)NULL) X fwrite(s_bss,SCNHSZ,1,fp); X fwrite(s_sri,SCNHSZ,1,fp); X fwrite(s_mir,SCNHSZ,1,fp); X if (s_domainhdr->tsize-apollo_start_size != 0) X fwrite(text_ptr,s_domainhdr->tsize-apollo_start_size,1,fp); X if (apollo_start_size != 0) X fwrite(apollo_start,apollo_start_size,1,fp); X if (s_domainhdr->dsize-n_patches != 0) X fwrite(data_ptr,s_domainhdr->dsize-n_patches,1,fp); X if (n_patches != 0) X fwrite(s_patches,n_patches,1,fp); X if (aptv_ptr != (char *)NULL) X fwrite(aptv_ptr,aptv_size,1,fp); X if (aptv_size != s_aptv->s_size) X fwrite(&zero,sizeof(short),1,fp); X fwrite(sri_recs,s_sri->s_size,1,fp); X fwrite(mir_recs,s_mir->s_size,1,fp); X if (tr.r_vaddr != 0) X fwrite(&tr,RELSZ,1,fp); X if (n_t_reloc != 0) X fwrite(s_t_reloc,RELSZ,n_t_reloc,fp); X if (dr.r_vaddr != 0) X fwrite(&dr,RELSZ,1,fp); X if (n_d_reloc != 0) X fwrite(s_d_reloc,RELSZ,n_d_reloc,fp); X if (ar.r_vaddr != 0) X fwrite(&ar,RELSZ,1,fp); X if (n_a_reloc != 0) X fwrite(s_a_reloc,RELSZ,n_a_reloc,fp); X if (n_t_lines != 0) X fwrite(s_t_lines,LINESZ,n_t_lines,fp); X fwrite(s_syms,SYMESZ,n_syms,fp); X n_string += sizeof n_string; X fwrite(&n_string,sizeof n_string,1,fp); X n_string -= sizeof n_string; X fwrite(s_string,1,n_string,fp); X X fclose(fp); X s_aptv->s_size = aptv_size; X s_text->s_size -= apollo_start_size; X if (s_data != (struct scnhdr *)NULL) X s_data->s_size -= n_patches; X} /* end of coff_write */ X Xchar *coff_findsym(vaddr) Xlong vaddr; X{ X register long i; X register struct syment *s; X X if ((struct syment *)s_syms == (struct syment *)NULL) X return (char *)NULL; X X for (i = 0; i < n_syms; i++) X { /* fix the symbol table */ X s = (struct syment *)((long)s_syms + (i * SYMESZ)); X if (s->n_value == vaddr) X { /* if found the symbol */ X if (s->n_zeroes != 0) X return s->n_name; X else X return &s_string[s->n_offset - sizeof n_string]; X } X i += s->n_numaux; X } X return (char *)NULL; X} /* end of coff_findsym */ X Xchar *coff_findsym_reloc(vaddr,value) Xlong vaddr; Xlong *value; X{ X register long i; X register struct syment *s; X register struct reloc *r; X X if ((struct syment *)s_syms == (struct syment *)NULL) X return (char *)NULL; X X for (i = 0; i < n_t_reloc; i++) X { /* text relocations */ X r = (struct reloc *)((long)s_t_reloc + (i * RELSZ)); X if (r->r_vaddr == vaddr) X { /* if have sym */ X s = (struct syment *)((long)s_syms + (r->r_symndx * SYMESZ)); X *value = s->n_value; X if (s->n_zeroes != 0) X return s->n_name; X else X return &s_string[s->n_offset - sizeof n_string]; X } X } X for (i = 0; i < n_d_reloc; i++) X { /* data relocations */ X r = (struct reloc *)((long)s_d_reloc + (i * RELSZ)); X if (r->r_vaddr == vaddr) X { /* if have sym */ X s = (struct syment *)((long)s_syms + (r->r_symndx * SYMESZ)); X *value = s->n_value; X if (s->n_zeroes != 0) X return s->n_name; X else X return &s_string[s->n_offset - sizeof n_string]; X } X } X for (i = 0; i < n_a_reloc; i++) X { /* aptv relocations */ X r = (struct reloc *)((long)s_a_reloc + (i * RELSZ)); X if (r->r_vaddr == vaddr) X { /* if have sym */ X s = (struct syment *)((long)s_syms + (r->r_symndx * SYMESZ)); X *value = s->n_value; X if (s->n_zeroes != 0) X return s->n_name; X else X return &s_string[s->n_offset - sizeof n_string]; X } X } X return (char *)NULL; X} /* end of coff_findsym_reloc */ END_OF_FILE if test 53153 -ne `wc -c <'coff.c'`; then echo shar: \"'coff.c'\" unpacked with wrong size! fi chmod +x 'coff.c' # end of 'coff.c' fi echo shar: End of archive 4 \(of 4\). cp /dev/null ark4isdone MISSING="" for I in 1 2 3 4 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 4 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0