[comp.sys.apollo] GCC & G++ on Apollo's; Part 2 of 4

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