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 2 (of 4)."
# Contents: a_out.c convert.c undefined.c
# Wrapped by dclemans@dclemans on Mon May 29 13:06:56 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'\" \(18290 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 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 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 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 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)
X printf("** %d symbols (for symbolic debugging?) skipped.\n",skipped_syms);
X} /* end of doConversion */
END_OF_FILE
if test 18290 -ne `wc -c <'a_out.c'`; then
echo shar: \"'a_out.c'\" unpacked with wrong size!
fi
chmod +x 'a_out.c'
# 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
chmod +x 'convert.c'
# 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'\" \(14653 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;
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;
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 word = (long *)memaddr;
X *word += s->n_value;
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 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 < reloc_count; i++)
X { /* an existing reference that we can use? */
X ar = (struct reloc *)((long)reloc_tab + (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 /* 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 CMPIL6_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 case 0:
X case 1:
X case 2:
X case 3:
X case 4:
X case 5:
X case 6:
X case 7:
X /* 8 bytes, relocatable bytes 4-7 */
X word = (long *)instr;
X instr = (short *)(memaddr - sizeof(short) - sizeof(short));
X if (*instr == BTST_INSTR)
X { /* then we know... */
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 }
X /* FALL THROUGH */
X default: /* oh well... we lose */
X printf("** unable to handle shared library reference: name=%s,vaddr=0x%08x\n",name,r->r_vaddr);
X printf("** *instr=0x%04x, *word=0x%08x\n",*instr & 0xFFFF,*word);
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 14653 -ne `wc -c <'undefined.c'`; then
echo shar: \"'undefined.c'\" unpacked with wrong size!
fi
chmod +x 'undefined.c'
# 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