dclemans@mentor.com (Dave Clemans @ APD x1292) (06/15/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 2 (of 4)." # Contents: a_out.c convert.c undefined.c # Wrapped by dclemans@dclemans on Wed Jun 14 14:59:42 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'a_out.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'a_out.c'\" else echo shar: Extracting \"'a_out.c'\" \(18458 characters\) sed "s/^X//" >'a_out.c' <<'END_OF_FILE' X/* X * Read in a GNU format object file, write out a COFF format file. X * We must be able to fit the entire file into memory. X */ X#include <stdio.h> Xextern char *malloc(); X X#include "/gnu/src/gdb/a.out.gnu.h" X#include "/gnu/src/gdb/stab.gnu.h" X X#include "gnu2coff.h" X XdoConversion(file) Xchar *file; X{ X register long i; X FILE *fp; X struct exec header; X char *file_text; X char *file_data; X char *file_syms; X char *file_trel; X char *file_drel; X long file_str_size,file_nsyms,file_ntrel,file_ndrel,text_sym,data_sym,bss_sym; X long *file_symcon; X char *file_str; X register struct nlist *symbol; X register struct relocation_info *relocation; X long skipped_syms = 0; X X fp = fopen(file,"r"); X if (fp == (FILE *)NULL) X { /* a good file? */ X fprintf(stderr,"gnu2coff: can't open file: %s\n",file); X exit(1); X } X X if (fread(&header,1,sizeof header,fp) != sizeof header) X { /* a good header? */ X fprintf(stderr,"gnu2coff: can't read file header: %s\n",file); X exit(1); X } X X if (show_headers) X { /* print the info? */ X printf("%s: magic=0%o,machtype=%d\n",file,N_MAGIC(header),N_MACHTYPE(header)); X printf("\ttext=%d bytes, data=%d bytes, bss=%d bytes\n",header.a_text,header.a_data,header.a_bss); X printf("\tstart address=0x%x\n",header.a_entry); X printf("\tsymbol table=%d bytes, text relocation=%d bytes, data relocation=%d bytes\n", X header.a_syms,header.a_trsize,header.a_drsize); X } X fseek(fp,(long)N_STROFF(header),0); X if (header.a_syms != 0) X { /* if a string table should be there? */ X if (fread(&file_str_size,sizeof file_str_size,1,fp) != 1) X { /* a good read? */ X fprintf(stderr,"gnu2coff: can't get string table size from file: %s\n",file); X exit(1); X } X if (show_headers) X printf("\tstring table size=%d bytes\n",file_str_size); X } X else file_str_size = 0; X X file_text = (char *)malloc(header.a_text); X if (file_text == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for text\n"); X exit(1); X } X file_data = (char *)malloc(header.a_data); X if (file_data == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for data\n"); X exit(1); X } X if (header.a_syms != 0) X { /* if a symbol table needed */ X file_syms = (char *)malloc(header.a_syms); X if (file_syms == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for symbols\n"); X exit(1); X } X file_str = (char *)malloc(file_str_size); X if (file_str == (char *)NULL) X { /* enough memory */ X fprintf(stderr,"gnu2coff: no memory for string table\n"); X exit(1); X } X } X else file_str = file_syms = (char *)NULL; X if (header.a_trsize != 0) X { /* if text relocation needed */ X file_trel = (char *)malloc(header.a_trsize); X if (file_trel == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for text relocation\n"); X exit(1); X } X } X else file_trel = (char *)NULL; X if (header.a_drsize != 0) X { /* if data relocation needed */ X file_drel = (char *)malloc(header.a_drsize); X if (file_drel == (char *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for symbols\n"); X exit(1); X } X } X else file_drel = (char *)NULL; X X fseek(fp,(long)N_TXTOFF(header),0); X if (fread(file_text,1,header.a_text,fp) != header.a_text) X { /* a good read? */ X fprintf(stderr,"gnu2coff: can't read file text: %s\n",file); X exit(1); X } X fseek(fp,(long)N_DATOFF(header),0); X if (fread(file_data,1,header.a_data,fp) != header.a_data) X { /* a good header? */ X fprintf(stderr,"gnu2coff: can't read file data: %s\n",file); X exit(1); X } X fseek(fp,(long)N_SYMOFF(header),0); X if (file_syms != (char *)NULL) X { /* if a symbol table */ X if (fread(file_syms,1,header.a_syms,fp) != header.a_syms) X { /* a good read? */ X fprintf(stderr,"gnu2coff: can't read file symbols: %s\n",file); X exit(1); X } X } X fseek(fp,(long)N_TRELOFF(header),0); X if (file_trel != (char *)NULL) X { /* if text relocation */ X if (fread(file_trel,1,header.a_trsize,fp) != header.a_trsize) X { /* a good read? */ X fprintf(stderr,"gnu2coff: can't read file text relocation: %s\n",file); X exit(1); X } X } X fseek(fp,(long)N_DRELOFF(header),0); X if (file_drel != (char *)NULL) X { /* if data relocation */ X if (fread(file_drel,1,header.a_drsize,fp) != header.a_drsize) X { /* a good read? */ X fprintf(stderr,"gnu2coff: can't read file data relocation: %s\n",file); X exit(1); X } X } X fseek(fp,(long)N_STROFF(header),0); X if (file_str != (char *)NULL) X { /* if a string table */ X if (fread(file_str,1,file_str_size,fp) != file_str_size) X { /* a good read? */ X fprintf(stderr,"gnu2coff: can't read file string table: %s\n",file); X exit(1); X } X } X X file_ntrel = header.a_trsize / sizeof(struct relocation_info); X file_ndrel = header.a_drsize / sizeof(struct relocation_info); X file_nsyms = header.a_syms / sizeof(struct nlist); X file_symcon = (long *)malloc(file_nsyms * sizeof(long)); X if (file_symcon == (long *)NULL) X { /* enough memory? */ X fprintf(stderr,"gnu2coff: no memory for symbol number conversion\n"); X exit(1); X } X for (i = 0; i < file_nsyms; i++) X file_symcon[i] = -1; X X if (show_headers) X { /* print the info? */ X printf("\tnumber of symbols=%d\n",file_nsyms); X printf("\tnumber of text relocation entries=%d\n",file_ntrel); X printf("\tnumber of data relocation entries=%d\n",file_ndrel); X } X X symbol = (struct nlist *)file_syms; X for (i = 0; i < file_nsyms; i++) X { /* set up symbol names */ X if (symbol[i].n_un.n_strx > 0 && symbol[i].n_type != N_INDR) X symbol[i].n_un.n_name = &file_str[symbol[i].n_un.n_strx]; X else if (symbol[i].n_type == N_INDR) X symbol[i].n_un.n_next = &symbol[i+1]; X } X X if (show_code) X disasm("Text section from a.out file",file_text,header.a_text,0); X if (show_symbols) X { /* print the info? */ X for (i = 0; i < file_nsyms; i++) X { /* dump the symbol table */ X printf("0x%08x 0x%02x 0x%02x %6d ",symbol[i].n_value,symbol[i].n_type&0xFF, X symbol[i].n_other&0xFF,symbol[i].n_desc); X if (symbol[i].n_type != N_INDR && symbol[i].n_un.n_strx != 0) X printf("%s\n",symbol[i].n_un.n_name); X else if (symbol[i].n_type == N_INDR) X printf("0x%x\n",symbol[i].n_un.n_next); X else printf("-\n"); X } X } X X if (show_relocation) X { /* print the info? */ X printf("*Text relocations: %d\n",file_ntrel); X relocation = (struct relocation_info *)file_trel; X for (i = 0; i < file_ntrel; i++) X { /* dump out relocations */ X printf("vaddr=0x%08x pcrel=%1d length=%2d ",relocation[i].r_address,relocation[i].r_pcrel,relocation[i].r_length); X printf("*instr=0x%04x ",(*(short *)&file_text[relocation[i].r_address-2])&0xFFFF); X if (relocation[i].r_length == 2) X printf("*vaddr=0x%08x ",*(long *)&file_text[relocation[i].r_address]); X if (relocation[i].r_extern == 0) X printf("%d\n",relocation[i].r_symbolnum); X else X { /* try to print symbol name */ X if (symbol[relocation[i].r_symbolnum].n_type != N_INDR && symbol[relocation[i].r_symbolnum].n_un.n_strx != 0) X printf("%s\n",symbol[relocation[i].r_symbolnum].n_un.n_name); X else if (symbol[relocation[i].r_symbolnum].n_type == N_INDR) X printf("0x%x\n",symbol[relocation[i].r_symbolnum].n_un.n_next); X else printf("-\n"); X } X } X printf("*Data relocations: %d\n",file_ndrel); X relocation = (struct relocation_info *)file_drel; X for (i = 0; i < file_ndrel; i++) X { /* dump out relocations */ X printf("vaddr=0x%08x pcrel=%1d length=%2d ",relocation[i].r_address,relocation[i].r_pcrel,relocation[i].r_length); X if (relocation[i].r_length == 2) X printf("*vaddr=0x%08x ",*(long *)&file_data[relocation[i].r_address]); X if (relocation[i].r_extern == 0) X printf("%d\n",relocation[i].r_symbolnum); X else X { /* try to print symbol name */ X if (symbol[relocation[i].r_symbolnum].n_type != N_INDR && symbol[relocation[i].r_symbolnum].n_un.n_strx != 0) X printf("%s\n",symbol[relocation[i].r_symbolnum].n_un.n_name); X else if (symbol[relocation[i].r_symbolnum].n_type == N_INDR) X printf("0x%x\n",symbol[relocation[i].r_symbolnum].n_un.n_next); X else printf("-\n"); X } X } X } X X coff_filehdr(); X coff_text(file_text,header.a_text); X#ifdef never X if (header.a_data > 0) X coff_data(file_data,header.a_data); X if (header.a_bss > 0) X coff_bss(header.a_bss); X#else X coff_data(file_data,header.a_data); X coff_bss(header.a_bss); X#endif X text_sym = -STEXT; X data_sym = -SDATA; X bss_sym = -SBSS; X X symbol = (struct nlist *)file_syms; X for (i = 0; i < file_nsyms; i++) X { /* convert the symbol table */ X switch ((symbol[i].n_type & 0xFF) & ~N_EXT) X { /* what kind of symbol */ X case N_FN: /* a file name */ X case N_SO: X case N_SOL: X file_symcon[i] = coff_def_file(symbol[i].n_un.n_name); X break; X case N_TEXT: /* basic text symbol */ X file_symcon[i] = coff_def_symbol(symbol[i].n_un.n_name, X symbol[i].n_value,STEXT,symbol[i].n_type & N_EXT); X if (try_sym_conversion) X sym_enter(&symbol[i],file_symcon[i]); X break; X case N_DATA: /* basic data symbol */ X file_symcon[i] = coff_def_symbol(symbol[i].n_un.n_name, X symbol[i].n_value,SDATA,symbol[i].n_type & N_EXT); X break; X case N_BSS: /* basic bss symbol */ X file_symcon[i] = coff_def_symbol(symbol[i].n_un.n_name, X symbol[i].n_value,SBSS,symbol[i].n_type & N_EXT); X break; X case N_UNDF: /* undefined name */ X if (symbol[i].n_value == 0) X file_symcon[i] = coff_def_undef(symbol[i].n_un.n_name, X symbol[i].n_type & N_EXT); X else X file_symcon[i] = coff_def_symbol(symbol[i].n_un.n_name, X symbol[i].n_value,0,symbol[i].n_type & N_EXT); X break; X case N_FUN: /* end of function */ X case N_SLINE: /* text line number */ X case N_LSYM: /* local symbol */ X case N_RSYM: /* register variable */ X case N_PSYM: /* a function parameter */ X case N_LBRAC: /* start of basic block */ X case N_RBRAC: /* end of basic block */ X case N_GSYM: /* global variable */ X if (try_sym_conversion) X sym_enter(&symbol[i],0); X break; X case N_TYPE: /* type name? */ X skipped_syms++; X break; X case N_ABS: /* absolute variable */ X skipped_syms++; X break; X case N_PC: /* global variable */ X skipped_syms++; X break; X case N_FNAME: /* function name */ X skipped_syms++; X break; X case N_STSYM: /* data symbol */ X skipped_syms++; X break; X case N_LCSYM: /* bss symbol */ X skipped_syms++; X break; X case N_SSYM: /* structure variable */ X skipped_syms++; X break; X case N_ENTRY: /* alternate entry point */ X skipped_syms++; X break; X case N_DSLINE: /* data line number */ X skipped_syms++; X break; X case N_BSLINE: /* bss line number */ X skipped_syms++; X break; X case N_BCOMM: /* start common block */ X skipped_syms++; X break; X case N_ECOMM: /* end common block */ X case N_ECOML: X skipped_syms++; X break; X case N_BINCL: /* start of include */ X skipped_syms++; X break; X case N_EINCL: /* end of previous include */ X skipped_syms++; X break; X case N_EXCL: /* excluded include file */ X skipped_syms++; X break; X default: X printf("** unknown ** "); X if (symbol[i].n_type != N_INDR && symbol[i].n_un.n_strx != 0) X printf("%s\n",symbol[i].n_un.n_name); X else if (symbol[i].n_type == N_INDR) X printf("0x%x\n",symbol[i].n_un.n_next); X else printf("-\n"); X break; X } X } X if (try_sym_conversion) X sym_enter((struct nlist *)NULL,0); X X relocation = (struct relocation_info *)file_trel; X for (i = 0; i < file_ntrel; i++) X { /* convert text relocations */ X if (relocation[i].r_pcrel) X { /* undo the pc relative stuff */ X long *word; X short *instr; X X word = (long *)&file_text[relocation[i].r_address]; X *word += relocation[i].r_address; /* assumes text starts at zero */ X instr = (short *)&file_text[relocation[i].r_address-sizeof(short)]; X if (*instr == BSR_INSTR) X *instr = JSR_INSTR; X else printf("** Possible bad text pc-relative relocation\n"); X } X if (relocation[i].r_extern == 0) X { /* section relative */ X if (relocation[i].r_length != 2) X printf("** Short relocs not implemented!\n"); X else if (relocation[i].r_symbolnum == N_TEXT) X coff_text_reloc(relocation[i].r_address,text_sym); X else if (relocation[i].r_symbolnum == N_DATA) X coff_text_reloc(relocation[i].r_address,data_sym); X else if (relocation[i].r_symbolnum == N_BSS) X coff_text_reloc(relocation[i].r_address,bss_sym); X else printf("** Unknown section reference! %d\n",relocation[i].r_symbolnum); X } X else X { X if (relocation[i].r_length != 2) X printf("** Short relocs not implemented!\n"); X else if (file_symcon[relocation[i].r_symbolnum] == -1) X printf("** Symbol not present!\n"); X else coff_text_reloc(relocation[i].r_address,file_symcon[relocation[i].r_symbolnum]); X } X } X coff_fix_undefined(); X relocation = (struct relocation_info *)file_drel; X for (i = 0; i < file_ndrel; i++) X { /* convert data relocations */ X if (relocation[i].r_pcrel) X { /* huh? */ X printf("** pc relative relocation in data section?\n"); X continue; X } X if (relocation[i].r_extern == 0) X { /* section relative */ X if (relocation[i].r_length != 2) X printf("** Short relocs not implemented!\n"); X else if (relocation[i].r_symbolnum == N_TEXT) X coff_data_reloc(relocation[i].r_address,text_sym); X else if (relocation[i].r_symbolnum == N_DATA) X coff_data_reloc(relocation[i].r_address,data_sym); X else if (relocation[i].r_symbolnum == N_BSS) X coff_data_reloc(relocation[i].r_address,bss_sym); X else printf("** Unknown section reference! %d\n",relocation[i].r_symbolnum); X } X else X { X if (relocation[i].r_length != 2) X printf("** Short relocs not implemented!\n"); X else if (file_symcon[relocation[i].r_symbolnum] == -1) X printf("** Symbol not present!\n"); X else coff_data_reloc(relocation[i].r_address,file_symcon[relocation[i].r_symbolnum]); X } X } X X if (cplusplus_mode) X { /* need C++ static constructor/destructor stuff? */ X long vaddr,*memaddr; X X vaddr = coff_patch_space(sizeof(long)*3,&memaddr); X memaddr[0] = 0; X memaddr[1] = cplusplus_ctor; X memaddr[2] = cplusplus_dtor; X if (cplusplus_ctor != 0) X coff_data_reloc(header.a_data+vaddr+sizeof(long),text_sym); X if (cplusplus_dtor != 0) X coff_data_reloc(header.a_data+vaddr+sizeof(long)+sizeof(long),text_sym); X (void) coff_def_symbol("_GLOBAL_$$LINK",header.a_text+header.a_data+vaddr,SDATA,0); X if (cplusplus_main) X { /* set up header for static constructor/destructor stuff */ X long new_vaddr; X X new_vaddr = coff_patch_space(sizeof(long),&memaddr); X memaddr[0] = header.a_text+header.a_data+vaddr; X coff_data_reloc(header.a_data+new_vaddr,data_sym); X cplusplus_gsym = coff_def_symbol("__GLOBAL_$$HEADER",header.a_text+header.a_data+new_vaddr,SDATA,1); X } X } X X coff_def_sri(); X coff_def_mir(file); X coff_finish(); X coff_write(file); X X if (skipped_syms != 0 && try_sym_conversion) X printf("** %d symbols (for symbolic debugging?) skipped.\n",skipped_syms); X} /* end of doConversion */ END_OF_FILE if test 18458 -ne `wc -c <'a_out.c'`; then echo shar: \"'a_out.c'\" unpacked with wrong size! fi # end of 'a_out.c' fi if test -f 'convert.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'convert.c'\" else echo shar: Extracting \"'convert.c'\" \(16463 characters\) sed "s/^X//" >'convert.c' <<'END_OF_FILE' X/* X * 68000 Disassembler: X * X * These files provide a simple 68000 disassembler. The program "disassem" X * will read standard DOS object files, and disassemble the code sections. X * Data sections are dumped in hex, symbol definitions are listed appropriately. X * My main interest was in dumping executable files, so I haven't integrated X * the symbols with the disassembled code. The file "convert.c" is the X * procedure which actually converts a single instruction to a text string. If X * you want to disassemble information in memory, or from some other object X * file format it should be easy to change the disassem program. The X * disassembler will convert any valid instruction to text, it will not however X * notice all invalid combinations of addressing modes. Thus, some invalid X * instruction codes may be printed as valid. X * You may copy-change-use this program as you like. X * X * Bill Rogers X * Comp Sci Dept. X * University of WAIKATO X * X * Simple string & ascii support by Dave Clemans X */ X#include <stdio.h> X#include <ctype.h> Xextern char *coff_findsym_reloc(); X Xstatic int n_words; Xstatic short *wordptr; Xstatic short *wordend; Xstatic long viraddr; X#define nextcodeword() (&wordptr[n_words] < wordend ? wordptr[n_words++] : 0xFFFF) X Xstruct instruction { X unsigned opcode: 4; X unsigned destreg: 3; X unsigned extend: 3; X unsigned srcmode: 3; X unsigned srcreg: 3; X }; X Xstruct shiftbits { X unsigned opcode: 4; X unsigned count: 3; X unsigned direct: 1; X unsigned optype: 2; X unsigned opmode: 1; X unsigned shift: 2; X unsigned dest: 3; X }; X Xstruct testbits { X unsigned opcode: 4; X unsigned ccode: 4; X unsigned offset: 8; X }; X Xunion { X struct instruction iview; X struct shiftbits s; X struct testbits tview; X short sview; } cheat; X Xchar opline[120], *opp, *valp; X Xstartline() X{ X valp=opline; opp=opline+34; X} X Xdisplayline() X{ X while (valp<(opline+34)) *valp++=' '; X *opp='\0'; X printf("%s\n",opline); X} X Xpadd() X{ X while (opp<(opline+42)) opchar(' '); X} X Xopchar(c) Xchar c; X{ X *opp++=c; X} X Xopstring(s) Xchar *s; X{ X while (*s!='\0') *opp++ = *s++; X} X Xopcode(s) Xchar *s; X{ X int n=5; X while (*s!='\0' & n-- >0) *opp++ = *s++; X} X Xopint(v) Xint v; X{ X int t; X if (v<=0) *opp++='0'; X else { if ((t=v/10)>0) opint(t); *opp++ = v%10+'0'; }; X} X Xophex(v,n) Xint v,n; X{ X char c; X while (n-- > 0) X *opp++ = (c=(v>>(n<<2)) & 0xF) <= 9 ? c+'0' : c-10+'A'; X} X Xlefthex(v,b) Xint v,b; X{ X int n=4; X char c; X while (b-->0) *valp++ = ' '; X while (n-->0) X *valp++ = (c=(v>>(n<<2)) & 0xF) <= 9 ?c+'0':c-10+'A'; X} X Xmynext(b) Xint b; X{ X int v; X lefthex(v=nextcodeword(),b); X return v; X} X Xinvalid() X{ X opstring(".WORD"); padd(); ophex(cheat.sview,4); X} X Xint srckind; X Xsourcekind(k) Xint k; X{ X opchar('.'); X switch (k) { X case 0: case 4: opchar('B'); srckind=0; break; X case 1: case 5: case 3: opchar('W'); srckind=1; break; X case 2: case 6: case 7: opchar('L'); srckind=2; break; X } X} X Xshiftinstruction() X{ X int t; X static char *mnemonics[8] = X { "ASR", "ASL", "LSR", "LSL", X "ROXR", "ROXL", "ROR", "ROL" }; X if (cheat.s.optype==3) { X opstring(mnemonics[(cheat.s.count<<1)+cheat.s.direct]); X padd(); X operand(cheat.iview.srcmode,cheat.iview.srcreg); X } X else { X opstring(mnemonics[(cheat.s.shift<<1)+cheat.s.direct]); X sourcekind(cheat.s.optype); X padd(); X if (cheat.s.opmode==0) { X opchar('#'); X opint( (t=cheat.s.count)==0 ? 8 : t ); X } X else X operand(0,cheat.s.count); X opchar(','); X operand(0,cheat.s.dest); X } X} X Xreference() X{ X register char *p; X long opnd; X char buffer[32]; X long val; X X val = 0; X p = coff_findsym_reloc(viraddr+(n_words*sizeof(short)),&val); X if (p == (char *)NULL) X { /* just a normal number */ X ophex(mynext(1),4); X ophex(mynext(0),4); X return; X } X opnd = ((long)mynext(1) << 16) | ((long)mynext(0) & 0xFFFF); X if (opnd != 0) X opnd -= val; X opstring(p); X if (opnd != 0 && val != 0) X { /* if an offset */ X opchar('+'); X sprintf(buffer,"0x%X",opnd); X opstring(buffer); X } X} X Xoperand(mode,reg) Xint mode,reg; X{ X struct indexword { X unsigned dora :1; X unsigned ireg :3; X unsigned size :1; X unsigned junk :3; X unsigned disp :8; X }; X union { X short sh; X struct indexword ind; X } mycheat; X switch (mode) { X case 0: opchar('D'); opint(reg); break; X case 1: opchar('A'); opint(reg); break; X case 2: opstring("(A"); opint(reg); opchar(')'); break; X case 3: opstring("(A"); opint(reg); opstring(")+"); X break; X case 4: opstring("-(A"); opint(reg); opchar(')'); break; X case 5: ophex(mynext(1),4); X opstring("(A"); opint(reg); opchar(')'); break; X case 6: mycheat.sh=mynext(1); X ophex(mycheat.ind.disp,2); X opstring("(A"); opint(reg); opchar(','); X opchar(mycheat.ind.dora==0 ? 'D' : 'A'); X opint(mycheat.ind.ireg); X opchar('.'); X opchar(mycheat.ind.size==0 ? 'W' : 'L'); X opchar(')'); break; X case 7: switch (reg) { X case 0: ophex(mynext(1),4); break; X case 1: /* ophex(mynext(1),4); ophex(mynext(0),4); */ reference(); break; X case 2: opchar('+'); ophex(mynext(1),4); break; X case 3: mycheat.sh=mynext(1); X opchar('+'); X ophex(mycheat.ind.disp,2); X opchar('('); X opchar(mycheat.ind.dora==0 ? 'D' : 'A'); X opint(mycheat.ind.ireg); X opchar('.'); X opchar(mycheat.ind.size==0 ? 'W' : 'L'); X opchar(')'); X break; X case 4: opchar('#'); X switch (srckind) { X case 0: ophex(mynext(1),2); break; X case 1: ophex(mynext(1),4); break; X case 2: ophex(mynext(1),4); ophex(mynext(0),4); break; X }; X break; X } X } X} X Xconditioncode(cc) Xint cc; X{ X char *codes = "RASRHILSCCCSNEEQVCVSPLMIGELTGTLE"; X if (cc>1 || cheat.iview.opcode==6) { X opchar(codes[cc<<1]); X opchar(codes[(cc<<1)+1]); X } X else if (cc==0) opchar('T'); else opchar('F'); X} X Xhandlezero() X{ X int ext = cheat.iview.extend; X int dreg = cheat.iview.destreg; X int smod = cheat.iview.srcmode; X int sreg = cheat.iview.srcreg; X static char *opzero[] = {"OR","AND","SUB","ADD","","EOR","CMP",""}; X static char *opone[] = {"BTST","BCHG","BCLR","BSET"}; X if (ext<=2 & dreg!=4) { X opstring(opzero[dreg]); sourcekind(ext); padd(); X operand(7,4); opchar(','); X if (smod==7 && sreg==4) X if (srckind==0) opstring("CCR"); else opstring("SR"); X else operand(smod,sreg); X } X else if (ext<=3 & dreg==4) { X opstring(opone[ext]); padd(); X srckind = 0; operand(7,4); opchar(','); operand(smod,sreg); X } X else if (ext>=4) { X if (smod!=1) { X opstring(opone[ext-4]); padd(); X operand(0,dreg); opchar(','); operand(smod,sreg); X } X else { X opstring("MOVEP"); sourcekind(1+(ext&1)); padd(); X if (ext<=5) { X operand(5,sreg); opchar(','); operand(0,dreg); X } X else { X operand(0,dreg); opchar(','); operand(5,sreg); X } X } X } X else opstring("Invalid"); X} X Xbreakfurther(base) Xchar *base; X{ X int ext = cheat.iview.extend; X int dreg = cheat.iview.destreg; X int smod = cheat.iview.srcmode; X int sreg = cheat.iview.srcreg; X int comm,t; X X if ( ( (comm = *(base+ext)) & 0xF0 ) == 0x40 ) X comm = *( base+(8+(t=comm&0xF)+(t<<2)+(smod==0 ? 1 :(smod==1 ? 2 : 0)))); X if (comm==0) X opstring("Invalid"); X else { X opcode(base+(8+(t=comm&7)+(t<<2))); X if (comm & 8) sourcekind(ext); X if ((t=(comm>>4)&0xF)>=13) conditioncode(cheat.tview.ccode); X padd(); X switch (t) { X case 0: opstring("Invalid"); break; X case 1: operand(smod,sreg); opchar(','); operand(0,dreg); break; X case 2: operand(smod,sreg); opchar(','); operand(1,dreg); break; X case 3: operand(0,dreg); opchar(','); operand(smod,sreg); break; X case 4: opstring("Internal check fail"); break; X case 5: operand(3,sreg); opchar(','); operand(3,dreg); break; X case 6: operand(4,sreg); opchar(','); operand(4,dreg); break; X case 7: opchar('#'); opint(dreg); opchar(','); operand(smod,sreg); X break; X case 8: opchar('#'); ophex(cheat.tview.offset,2); opchar(','); X operand(0,dreg); break; X case 9: operand(1,dreg); opchar(','); operand(smod,sreg); break; X case 13: operand(smod,sreg); break; X case 14: operand(0,sreg); opchar(','); operand(7,2); break; X case 15: if (cheat.tview.offset==0) X operand(7,2); X else { X opchar('+'); X ophex(cheat.tview.offset,2); X }; X break; X } X } X} X Xmoveinstruction(kind) Xint kind; X{ X opstring("MOVE"); X sourcekind(kind==1 ? 0 : (kind==2 ? 2 : 1)); X padd(); X operand(cheat.iview.srcmode,cheat.iview.srcreg); X opchar(','); X operand(cheat.iview.extend,cheat.iview.destreg); X} X Xstartrange(bit) Xint bit; X{ X operand(bit<=7 ? 0 : 1, bit%8); X} X Xendrange(first,bit) Xint first,bit; X{ X if (first<=7 && bit>7) { X endrange(first,7); X opchar('/'); X startrange(8); X first=8; X }; X if (bit>first) { X opchar('-'); X startrange(bit); X } X} X Xregisterlist(kkkk,mask) Xint kkkk,mask; X{ X int bit = 0; int inrange = -1; int some = 0; X while (bit <= 15) { X if ( ( kkkk ? (mask>>(15-bit)) : (mask>>bit) ) & 1 ) { X if (inrange<0) { X if (some) opchar('/'); X startrange(bit); X some=1; inrange=bit; X } X } X else { X if (inrange>=0) { X endrange(inrange,bit-1); X inrange = -1; X } X }; X bit++; X }; X if (inrange>=0) endrange(inrange,15); X} X Xspecialbits() X{ X int smod = cheat.iview.srcmode; X int sreg = cheat.iview.srcreg; X switch (smod) { X case 0: opstring("TRAP"); padd(); opchar('#'); opint(sreg); break; X case 1: opstring("Invalid"); break; X case 2: opstring("LINK"); padd(); operand(1,sreg); X opchar(','); srckind=1; operand(7,4); break; X case 3: opstring("UNLK"); padd(); operand(1,sreg); break; X case 4: opstring("MOVE"); padd(); operand(1,sreg); X opstring(",USP"); break; X case 5: opstring("MOVE"); padd(); opstring("USP,"); X operand(1,sreg); break; X case 6: switch (sreg) { X case 0: opstring("RESET"); break; X case 1: opstring("NOP"); break; X case 2: opstring("STOP"); padd(); srckind=1; operand(7,4); break; X case 3: opstring("RTE"); break; X case 4: opstring("Invalid"); break; X case 5: opstring("RTS"); break; X case 6: opstring("TRAPV"); break; X case 7: opstring("RTR"); break; X }; break; X case 7: opstring("Invalid"); break; X } X} X Xhandlefour() X{ X int ext = cheat.iview.extend; X int dreg = cheat.iview.destreg; X int smod = cheat.iview.srcmode; X int sreg = cheat.iview.srcreg; X int reglist; X static char *unaryA[] = {"NEGX","CLR","NEG","NOT","","TST"}; X static char *cross4[] = {"NBCD","PEA", "MOVEM.W","MOVEM.L", X "NBCD","SWAP","EXT.W", "EXT.L"}; X static char *jumps[] = {"JSR","JMP"}; X X if (ext<=2 && (dreg<=3 || dreg==5)) { X opstring(unaryA[dreg]); sourcekind(ext); padd(); operand(smod,sreg); X } X else if (dreg==4 && ext<=3) { X opstring(cross4[smod==0 ? ext+4 : ext]); padd(); X if (ext>=2 && smod!=0) { X registerlist(smod==4,mynext(1)); opchar(','); X }; X operand(smod,sreg); X } X else if (ext==2 || ext==3) { X if (dreg==6) { X opstring(cross4[ext]); padd(); reglist=mynext(1); X operand(smod==4 ? 3: smod ,sreg); opchar(','); registerlist(0,reglist); X } X else if (dreg==7) { X opstring(jumps[ext-2]); padd(); operand(smod,sreg); X } X else if (ext==3) { X switch (dreg) { X case 0: opstring("MOVE"); padd(); opstring("SR,"); X operand(smod,sreg); break; X case 1: opstring("Invalid"); break; X case 2: opstring("MOVE"); padd(); srckind=0; X operand(smod,sreg); opstring(",CCR"); break; X case 3: opstring("MOVE"); padd(); srckind=1; X operand(smod,sreg); opstring(",SR"); break; X case 5: opstring("TAS"); padd(); operand(smod,sreg); break; X } X } X } X else if (ext==7) { X opstring("LEA"); padd(); operand(smod,sreg); X opchar(','); operand(1,dreg); X } X else if (ext==6) { X opstring("CHK"); padd(); srckind=1; X operand(smod,sreg); opchar(','); operand(0,dreg); X } X else if (ext==1 && dreg==7) specialbits(); X else opstring("Invalid"); X} X Xchar *interpret[16] = { X/*0*/ "\0\0\0\0\0\0\0\0", X/*1*/ "", X/*2*/ "", X/*3*/ "", X/*4*/ "\0\0\0\0\0\0\0\0", X/*5*/ "\170\170\170\104\173\173\173\104ADDQ\0S\0\0\0\0DB\0\0\0SUBQ\0\321\321\342", X/*6*/ "\360\360\360\360\360\360\360\360B", X/*7*/ "\200\200\200\200\200\200\200\200MOVEQ", X/*8*/ "\30\30\30\21\104\105\105\22OR\0\0\0DIVU\0DIVS\0SBCD\0\70\23\143\0\0\70\0\0", X/*9*/ "\30\30\30\50\102\102\102\50SUB\0\0SUBX\0\70\31\151", X/*a*/ "\0\0\0\0\0\0\0\0", X/*b*/ "\30\30\30\50\103\103\103\50CMP\0\0EOR\0\0CMPM\0\71\71\132", X/*c*/ "\30\30\30\21\105\106\107\22AND\0\0MULU\0MULS\0ABCD\0EXG\0\0\70\23\143\0\0\70\64\224\0\0\70\0\64", X/*d*/ "\30\30\30\50\102\102\102\50ADD\0\0ADDX\0\70\31\151", X/*e*/ "", X/*f*/ "\0\0\0\0\0\0\0\0" X }; X Xdostring(words,memptr,addr) Xint words; Xchar *memptr; Xint addr; X{ X int j; X char c; X char buf[6]; X X n_words = 0; X wordptr = (short *)memptr; X startline(); X lefthex(addr>>16,0); lefthex(addr,0); X opstring("ASCII"); X padd(); X opchar('"'); X while (words--) X { /* while stuff to print */ X j = nextcodeword(); X c = (j >> 8) & 0xFF; X if (c >= ' ' && c < '\177' && c != '\\') X opchar(c); X else X { /* escape it */ X opchar('\\'); X switch(c) X { /* what escape */ X case '\\': X opchar(c); X break; X case '\t': X opchar('t'); X break; X case '\n': X opchar('n'); X break; X case '\r': X opchar('r'); X break; X default: X sprintf(buf,"%o",c&0xFF); X opstring(buf); X break; X } X } X c = j & 0xFF; X if (c >= ' ' && c < '\177' && c != '\\') X opchar(c); X else X { /* escape it */ X opchar('\\'); X switch(c) X { /* what escape */ X case '\\': X opchar(c); X break; X case '\t': X opchar('t'); X break; X case '\n': X opchar('n'); X break; X case '\r': X opchar('r'); X break; X default: X sprintf(buf,"%o",c&0xFF); X opstring(buf); X break; X } X } X } X opchar('"'); X displayline(); X} X Xint decode(memaddr,memend,addr) Xshort *memaddr; Xshort *memend; Xint addr; X X{ X int i,j; X X viraddr = addr; X wordptr = memaddr; X wordend = memend; X n_words = 0; X X /* X * Look for strings X */ X i = 0; X for (;;) X { /* while still a possibility */ X j = nextcodeword(); X if (j == 0x4e5e || j == 0x4e75) X { /* stop now (for probable unlk or rts instr) */ X n_words = 0; X wordptr = memaddr; X break; X } X if (isprint((j >> 8) & 0xFF) || isspace((j >> 8) & 0xFF)) X i++; X else X { /* could it be a string */ X if (((j >> 8) & 0xFF) != 0 || i < 5) X { /* no */ X wordptr = memaddr; X n_words = 0; X break; X } X dostring(n_words,memaddr,addr); X return n_words; X } X if (isprint(j & 0xFF) || isspace(j & 0xFF)) X i++; X else X { /* could it be a string */ X if ((j & 0xFF) != 0 || i < 5) X { /* no */ X wordptr = memaddr; X n_words = 0; X break; X } X dostring(n_words,memaddr,addr); X return n_words; X } X } X X startline(); X lefthex(addr>>16,0); lefthex(addr,0); X cheat.sview=mynext(1); X switch (cheat.iview.opcode) { X case 1: X case 2: X case 3: moveinstruction(cheat.iview.opcode); break; X case 0: handlezero(); break; X case 4: handlefour(); break; X case 5: X case 6: X case 7: X case 8: X case 9: X case 10: X case 11: X case 12: X case 13: X case 15: breakfurther(interpret[cheat.iview.opcode]); break; X case 14: shiftinstruction(); break; X }; X displayline(); X X return n_words; X} END_OF_FILE if test 16463 -ne `wc -c <'convert.c'`; then echo shar: \"'convert.c'\" unpacked with wrong size! fi # end of 'convert.c' fi if test -f 'undefined.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'undefined.c'\" else echo shar: Extracting \"'undefined.c'\" \(18227 characters\) sed "s/^X//" >'undefined.c' <<'END_OF_FILE' X/* X * Add appropriate entries to our "under construction" COFF X * file to handle the Apollo magic for accessing their X * shared libraries. X */ X#include <stdio.h> X#include <string.h> X#include <memory.h> X#include <a.out.h> X X#include <apollo/base.h> X#include <apollo/loader.h> X Xextern char *malloc(); Xextern char *realloc(); Xextern long time(); Xextern char *getcwd(); X X#include "gnu2coff.h" X Xextern struct scnhdr *s_text; Xextern struct scnhdr *s_data; Xextern struct reloc *s_t_reloc; extern long n_t_reloc; X Xextern void coff_text_reloc(); Xextern void coff_data_reloc(); Xextern long coff_aptv_entry(); Xextern long coff_patch_space(); X Xstatic int handle_as_fp(); Xstatic long handle_data_ref(); X Xvoid ref_undefined(name,memaddr,r,s,reloc_tab,reloc_count) Xchar *name; Xchar *memaddr; Xstruct reloc *r; Xstruct syment *s; Xstruct reloc *reloc_tab; Xlong reloc_count; X{ X register int i; X struct reloc *ar; X short *instr,*instr1; X long *word; X short length; X loader_$kg_lookup_opts lookup_opts; X long where; X X if (r->r_symndx < 0) /* if "special" symbol */ X return; X if (s->n_scnum != 0) /* if not an undefined reference */ X return; X X if (s->n_value != 0) X { /* do we think this is a bss reference? */ X#ifdef never X word = (long *)memaddr; X *word += s->n_value; X#endif X return; X } X X length = strlen(name); X lookup_opts = 0; X where = loader_$kg_symbol; X word = (long *)NULL; X (void) loader_$kg_lookup(name,length,where,lookup_opts,(void *)&word); X if (word == (long *)NULL) X { /* if not in shared library */ X s->n_type = T_NULL; X return; X } X X word = (long *)memaddr; X instr = (short *)(memaddr - sizeof(short)); X X switch (*instr) X { /* see if we can handle the reference */ X case JSR_INSTR: /* switch to go through aptv vector */ X if (handle_as_fp(name,memaddr,r,s,reloc_tab,reloc_count)) X return; X /* FALL THROUGH! */ X case JUMP_INSTR: X for (i = 0; i < reloc_count; i++) X { /* an existing reference that we can use? */ X ar = (struct reloc *)((long)reloc_tab + (i*RELSZ)); X if (ar->r_symndx == r->r_symndx) X { /* found a match? */ X *word = ar->r_vaddr - sizeof(short); X r->r_symndx = -SAPTV; X return; X } X } X /* else make new entry */ X *word = coff_aptv_entry(r->r_symndx); X coff_aptv_reloc(*word + sizeof(short),r->r_symndx); X r->r_symndx = -SAPTV; X s->n_type = T_NULL; X break; X case PEA_INSTR: X case LEA0_INSTR: X case LEA1_INSTR: X case LEA2_INSTR: X case LEA3_INSTR: X case LEA4_INSTR: X case LEA5_INSTR: X case LEA6_INSTR: X case LEA7_INSTR: X case MOVE0_INSTR: X case MOVE1_INSTR: X case MOVE2_INSTR: X case MOVE3_INSTR: X case MOVE4_INSTR: X case MOVE5_INSTR: X case MOVE6_INSTR: X case MOVE7_INSTR: X case CMP0_INSTR: X case CMP1_INSTR: X case CMP2_INSTR: X case CMP3_INSTR: X case CMP4_INSTR: X case CMP5_INSTR: X case CMP6_INSTR: X case CMP7_INSTR: X case CMPID0_INSTR: X case CMPID1_INSTR: X case CMPID2_INSTR: X case CMPID3_INSTR: X case CMPID4_INSTR: X case CMPID5_INSTR: X case CMPID6_INSTR: X case CMPID7_INSTR: X case CMPIA0_INSTR: X case CMPIA1_INSTR: X case CMPIA2_INSTR: X case CMPIA3_INSTR: X case CMPIA4_INSTR: X case CMPIA5_INSTR: X case CMPIA6_INSTR: X case CMPIA7_INSTR: X case MOVEA0_INSTR: X case MOVEA1_INSTR: X case MOVEA2_INSTR: X case MOVEA3_INSTR: X case MOVEA4_INSTR: X case MOVEA5_INSTR: X case MOVEA6_INSTR: X case MOVEA7_INSTR: X case MOVED0_INSTR: X case MOVED1_INSTR: X case MOVED2_INSTR: X case MOVED3_INSTR: X case MOVED4_INSTR: X case MOVED5_INSTR: X case MOVED6_INSTR: X case MOVED7_INSTR: X case MOVEAA0_INSTR: X case MOVEAA1_INSTR: X case MOVEAA2_INSTR: X case MOVEAA3_INSTR: X case MOVEAA4_INSTR: X case MOVEAA5_INSTR: X case MOVEAA6_INSTR: X case MOVEAA7_INSTR: X case MOVEDI0_INSTR: X case MOVEDI1_INSTR: X case MOVEDI2_INSTR: X case MOVEDI3_INSTR: X case MOVEDI4_INSTR: X case MOVEDI5_INSTR: X case MOVEDI6_INSTR: X case MOVEDI7_INSTR: X case MOVEWD0_INSTR: X case MOVEWD1_INSTR: X case MOVEWD2_INSTR: X case MOVEWD3_INSTR: X case MOVEWD4_INSTR: X case MOVEWD5_INSTR: X case MOVEWD6_INSTR: X case MOVEWD7_INSTR: X case MOVEWA0_INSTR: X case MOVEWA1_INSTR: X case MOVEWA2_INSTR: X case MOVEWA3_INSTR: X case MOVEWA4_INSTR: X case MOVEWA5_INSTR: X case MOVEWA6_INSTR: X case MOVEWA7_INSTR: X case MOVEMA0_INSTR: X case MOVEMA1_INSTR: X case MOVEMA2_INSTR: X case MOVEMA3_INSTR: X case MOVEMA4_INSTR: X case MOVEMA5_INSTR: X case MOVEMA6_INSTR: X case MOVEMA7_INSTR: X case CMPA0_INSTR: X case CMPA1_INSTR: X case CMPA2_INSTR: X case CMPA3_INSTR: X case CMPA4_INSTR: X case CMPA5_INSTR: X case CMPA6_INSTR: X case CMPA7_INSTR: X case CMPAA0_INSTR: X case CMPAA1_INSTR: X case CMPAA2_INSTR: X case CMPAA3_INSTR: X case CMPAA4_INSTR: X case CMPAA5_INSTR: X case CMPAA6_INSTR: X case CMPAA7_INSTR: X case ADDQ0_INSTR: X case ADDQ1_INSTR: X case ADDQ2_INSTR: X case ADDQ3_INSTR: X case ADDQ4_INSTR: X case ADDQ5_INSTR: X case ADDQ6_INSTR: X case ADDQ7_INSTR: X case SUBQ0_INSTR: X case SUBQ1_INSTR: X case SUBQ2_INSTR: X case SUBQ3_INSTR: X case SUBQ4_INSTR: X case SUBQ5_INSTR: X case SUBQ6_INSTR: X case SUBQ7_INSTR: X case ADDQL0_INSTR: X case ADDQL1_INSTR: X case ADDQL2_INSTR: X case ADDQL3_INSTR: X case ADDQL4_INSTR: X case ADDQL5_INSTR: X case ADDQL6_INSTR: X case ADDQL7_INSTR: X case SUBQL0_INSTR: X case SUBQL1_INSTR: X case SUBQL2_INSTR: X case SUBQL3_INSTR: X case SUBQL4_INSTR: X case SUBQL5_INSTR: X case SUBQL6_INSTR: X case SUBQL7_INSTR: X case ADD0_INSTR: X case ADD1_INSTR: X case ADD2_INSTR: X case ADD3_INSTR: X case ADD4_INSTR: X case ADD5_INSTR: X case ADD6_INSTR: X case ADD7_INSTR: X case ADDR0_INSTR: X case ADDR1_INSTR: X case ADDR2_INSTR: X case ADDR3_INSTR: X case ADDR4_INSTR: X case ADDR5_INSTR: X case ADDR6_INSTR: X case ADDR7_INSTR: X case SUB0_INSTR: X case SUB1_INSTR: X case SUB2_INSTR: X case SUB3_INSTR: X case SUB4_INSTR: X case SUB5_INSTR: X case SUB6_INSTR: X case SUB7_INSTR: X case SUBR0_INSTR: X case SUBR1_INSTR: X case SUBR2_INSTR: X case SUBR3_INSTR: X case SUBR4_INSTR: X case SUBR5_INSTR: X case SUBR6_INSTR: X case SUBR7_INSTR: X case ADDI0_INSTR: X case ADDI1_INSTR: X case ADDI2_INSTR: X case ADDI3_INSTR: X case ADDI4_INSTR: X case ADDI5_INSTR: X case ADDI6_INSTR: X case ADDI7_INSTR: X case SUBI0_INSTR: X case SUBI1_INSTR: X case SUBI2_INSTR: X case SUBI3_INSTR: X case SUBI4_INSTR: X case SUBI5_INSTR: X case SUBI6_INSTR: X case SUBI7_INSTR: X case CLR_INSTR: X case TSTW_INSTR: X case TST_INSTR: X /* 6 bytes, relocatable bytes 2-5 */ X *word = handle_data_ref(r->r_symndx,r->r_vaddr-sizeof(short),memaddr-sizeof(short), X sizeof(short) + sizeof(long)); X *instr = JUMP_INSTR; X coff_data_reloc(*word + sizeof(short) - s_text->s_size,r->r_symndx); X coff_data_reloc(*word + sizeof(short) + sizeof(long) + sizeof(short) X - s_text->s_size,-STEXT); X r->r_symndx = -SDATA; X s->n_type = T_NULL; X break; X case MOVEIL_INSTR: X case CMPIL_INSTR: X case MOVEMM0_INSTR: X /* 10 bytes, relocatable bytes 2-5 */ X *word = handle_data_ref(r->r_symndx,r->r_vaddr-sizeof(short),memaddr-sizeof(short), X sizeof(short) + sizeof(long) + sizeof(long)); X *instr = JUMP_INSTR; X coff_data_reloc(*word + sizeof(short) - s_text->s_size,r->r_symndx); X coff_data_reloc(*word + sizeof(short) + sizeof(long) + sizeof(long) + sizeof(short) X - s_text->s_size,-STEXT); X r->r_symndx = -SDATA; X s->n_type = T_NULL; X for (i = 0; i < n_t_reloc; i++) X { /* another reference to same instruction? */ X ar = (struct reloc *)((long)s_t_reloc + (i*RELSZ)); X if (ar->r_vaddr == r->r_vaddr+sizeof(long)) X { /* a secondary relocation for same instruction */ X coff_data_reloc(*word + sizeof(short) + sizeof(long) X - s_text->s_size,ar->r_symndx); X ar->r_symndx = -STEXT; X /* this leaves an "extra" text relocation floating around, */ X /* but it should hit only the text area that the patch we */ X /* just inserted skips around */ X } X } X break; X case MOVEAI0_INSTR: X case MOVEAI1_INSTR: X case MOVEAI2_INSTR: X case MOVEAI3_INSTR: X case MOVEAI4_INSTR: X case MOVEAI5_INSTR: X case MOVEAI6_INSTR: X case MOVEAI7_INSTR: X case MOVEAAI0_INSTR: X case MOVEAAI1_INSTR: X case MOVEAAI2_INSTR: X case MOVEAAI3_INSTR: X case MOVEAAI4_INSTR: X case MOVEAAI5_INSTR: X case MOVEAAI6_INSTR: X case MOVEAAI7_INSTR: X case MOVEWAAI0_INSTR: X case MOVEWAAI1_INSTR: X case MOVEWAAI2_INSTR: X case MOVEWAAI3_INSTR: X case MOVEWAAI4_INSTR: X case MOVEWAAI5_INSTR: X case MOVEWAAI6_INSTR: X case MOVEWAAI7_INSTR: X case CMPIL6_INSTR: X case MOVEIA0_INSTR: X case MOVEIA1_INSTR: X case MOVEIA2_INSTR: X case MOVEIA3_INSTR: X case MOVEIA4_INSTR: X case MOVEIA5_INSTR: X case MOVEIA6_INSTR: X case MOVEIA7_INSTR: X /* 8 bytes, relocatable bytes 2-5 */ X *word = handle_data_ref(r->r_symndx,r->r_vaddr-sizeof(short),memaddr-sizeof(short), X sizeof(short) + sizeof(long) + sizeof(short)); X *instr = JUMP_INSTR; X coff_data_reloc(*word + sizeof(short) - s_text->s_size,r->r_symndx); X coff_data_reloc(*word + sizeof(short) + sizeof(long) + sizeof(short) + sizeof(short) X - s_text->s_size,-STEXT); X r->r_symndx = -SDATA; X s->n_type = T_NULL; X break; X default: /* oh well... we lose (maybe) */ X /* either an error, or ... */ X /* 8 bytes, relocatable bytes 4-7, special case */ X word = (long *)instr; X instr = (short *)(memaddr - sizeof(short) - sizeof(short)); X switch (*instr) X { /* anything we know? */ X case BTST_INSTR: X case ANDW_INSTR: X case MOVEDL_INSTR: X case MOVEAL_INSTR: X case MOVEMAI0_INSTR: X case MOVEMAI1_INSTR: X case MOVEMAI2_INSTR: X case MOVEMAI3_INSTR: X case MOVEMAI4_INSTR: X case MOVEMAI5_INSTR: X case MOVEMAI6_INSTR: X case MOVEMAI7_INSTR: X *word = handle_data_ref(r->r_symndx,r->r_vaddr-sizeof(short)-sizeof(short), X memaddr-sizeof(short)-sizeof(short),sizeof(short) + sizeof(short) + sizeof(long)); X *instr = JUMP_INSTR; X coff_data_reloc(*word + sizeof(short) + sizeof(short) - s_text->s_size,r->r_symndx); X coff_data_reloc(*word + sizeof(short) + sizeof(short) + sizeof(long) + sizeof(short) X - s_text->s_size,-STEXT); X r->r_symndx = -SDATA; X r->r_vaddr -= sizeof(short); X s->n_type = T_NULL; X break; X default: X instr1 = (short *)((long)instr - sizeof(short)); X if (*instr1 == MOVEIL_INSTR) X { /* one final special case */ X /* 10 bytes, relocatable bytes 6-9 */ X word = (long *)instr; X *word = handle_data_ref(r->r_symndx,r->r_vaddr-sizeof(short)-sizeof(long), X memaddr-sizeof(short)-sizeof(long), X sizeof(short) + sizeof(long) + sizeof(long)); X *instr1 = JUMP_INSTR; X coff_data_reloc(*word + sizeof(short) + sizeof(long) - s_text->s_size,r->r_symndx); X coff_data_reloc(*word + sizeof(short) + sizeof(long) + sizeof(long) + sizeof(short) X - s_text->s_size,-STEXT); X r->r_symndx = -SDATA; X s->n_type = T_NULL; X for (i = 0; i < n_t_reloc; i++) X { /* another reference to same instruction? */ X ar = (struct reloc *)((long)s_t_reloc + (i*RELSZ)); X if (ar->r_vaddr == r->r_vaddr-sizeof(long)) X { /* a secondary relocation for same instruction */ X coff_data_reloc(*word + sizeof(short) X - s_text->s_size,ar->r_symndx); X ar->r_vaddr += sizeof(long); X ar->r_symndx = -STEXT; X /* this leaves an "extra" text relocation floating around, */ X /* but it should hit only the text area that the patch we */ X /* just inserted skips around */ X } X } X break; X } X instr1 = instr; X instr = (short *)word; X word = (long *)memaddr; X printf("** unable to handle shared library reference: name=%s,vaddr=0x%08x\n",name,r->r_vaddr); X printf("** *instr=0x%04x, *(instr-2)=0x%04x, *word=0x%08x\n", X *instr & 0xFFFF,*instr1 & 0xFFFF,*word); X break; X } X return; X } X} /* end of ref_undefined */ X Xstatic char *fp_library[] = X{ X "atof", X "ldexp", X (char *)NULL X}; X X/* X * GNU, Apollo have different conventions for returning floating point values from X * functions. This data patch is supposed to handle that. X * X * 00008130 retaddr: X * 00008130 0000 0000 OR.B #00,D0 X * 00008134 retval: X * 00008134 0000 0000 OR.B #00,D0 X * 00008138 0000 0000 OR.B #00,D0 X * 0000813C fppat: X * 0000813C 23DF 00000000 MOVE.L (A7)+,retaddr X * 00008142 487A FFF0 PEA +FFF0 X * 00008146 4EB9 00000000 JSR routine X * 0000814C 584F ADDQ.W #4,A7 X * 0000814E 203A FFE4 MOVE.L +FFE4,D0 X * 00008152 223A FFE4 MOVE.L +FFE4,D1 X * 00008156 2F3A FFD8 MOVE.L +FFD8,-(A7) X * 0000815A 4E75 RTS X */ Xstatic long float_patch[] = X{ X 0x0, 0x0, 0x0, 0x23df0000, 0x0000487a, 0xfff04eb9, 0x0, 0x584f203a, 0xffe4223a, 0xffe42f3a, 0xffd84e75 X}; X#define START_FP_JSR 0x0c X#define RELOC_FP_SAVE 0x0e X#define RELOC_FP_JSR 0x18 X Xstatic int handle_as_fp(name,memaddr,r,s,reloc_tab,reloc_count) Xchar *name; Xchar *memaddr; Xstruct reloc *r; Xstruct syment *s; Xstruct reloc *reloc_tab; Xlong reloc_count; X{ X register long i; X register struct reloc *ar; X long vaddr; X char *ptr; X long *word; X X for (i = 0; fp_library[i] != (char *)NULL; i++) X if (strcmp(fp_library[i],name) == 0) X break; X if (fp_library[i] == (char *)NULL) X { /* say to handle as normal function */ X return 0; X } X X word = (long *)memaddr; X X for (i = 0; i < reloc_count; i++) X { /* an existing reference that we can use? */ X ar = (struct reloc *)((long)reloc_tab + (i*RELSZ)); X if (ar->r_symndx == r->r_symndx) X { /* found a match? */ X *word = ar->r_vaddr - RELOC_FP_JSR + START_FP_JSR; X r->r_symndx = -SDATA; X return 1; X } X } X X vaddr = coff_patch_space(sizeof float_patch,&ptr); X memcpy(ptr,(char *)float_patch,sizeof float_patch); X X *word = s_text->s_size + s_data->s_size + vaddr + START_FP_JSR; X coff_data_reloc(s_data->s_size + vaddr + RELOC_FP_SAVE,-SDATA); X word = (long *)&ptr[RELOC_FP_SAVE]; X *word = s_data->s_size + vaddr + s_text->s_size; X coff_data_reloc(s_data->s_size + vaddr + RELOC_FP_JSR,r->r_symndx); X r->r_symndx = -SDATA; X s->n_type = T_NULL; X X return 2; X} /* end of handle_as_fp */ X Xstatic long handle_data_ref(symnum,viraddr,memaddr,length) Xlong symnum; Xlong viraddr; Xchar *memaddr; Xlong length; X{ X long vaddr; X long newlen; X char *ptr; X long *word; X short *instr; X X vaddr = coff_patch_space(length + sizeof(short) + sizeof(long),&ptr); X memcpy(ptr,memaddr,length); X ptr += length; X instr = (short *)ptr; X word = (long *)((long)ptr + sizeof(short)); X *instr = JUMP_INSTR; X *word = viraddr+length; X return vaddr+s_data->s_size+s_text->s_size; X} /* end of handle_data_ref */ END_OF_FILE if test 18227 -ne `wc -c <'undefined.c'`; then echo shar: \"'undefined.c'\" unpacked with wrong size! fi # end of 'undefined.c' fi echo shar: End of archive 2 \(of 4\). cp /dev/null ark2isdone 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