home *** CD-ROM | disk | FTP | other *** search
- /*
- ** getrel -- read a relocatable-object file
- */
- #include <stdio.h>
- #include "rel.h"
- #include "mac.h"
-
- /*
- ** get next REL item
- ** return itemcode on success, ERR on error
- ** on successful return:
- ** item = item code
- ** type = type of field
- ** field = value of field
- ** symbol = symbol name
- */
- getrel() {
- if(!getbits(1)) return (ERR); /* get 1 bit */
- if(field == 0) { /* absolute item */
- if(!getbits(8)) return (ERR); /* get next 8 bits */
- return (type = item = ABS); /* absolute item */
- }
- if(!getbits(2)) return (ERR); /* get next 2 bits */
- switch(type = item = field) {
- case 0: return (getspec()); /* special link item */
- case 1: /* program relative item */
- case 2: /* data relative item */
- case 3: /* common relative item */
- }
- if(getfld() == ERR) return (ERR); /* get next 16 bits */
- return (item); /* relative items */
- }
-
- getspec() { /* get next special item */
- if(!getbits(4)) return (ERR); /* get next 4 bits */
- type = ABS; /* default type */
- item = field + 4;
- switch(field) {
- case 0: /* entry symbol */
- case 1: /* select common block */
- case 2: /* program name */
- case 3: /* request library search */
- case 4: /* extension link items */
- if(getsym() == ERR) return (ERR);
- break;
- case 5: /* define common size */
- case 6: /* head of external reference chain */
- case 7: /* define entry point */
- if(gettyp() == ERR || getfld() == ERR || getsym() == ERR) return (ERR);
- break;
- case 8: /* external - offset */
- case 9: /* external + offset */
- case 10: /* size of data area */
- case 11: /* set loading location counter */
- case 12: /* chain addr (fill chain with lc) */
- case 13: /* size of program */
- if(gettyp() == ERR || getfld() == ERR) return (ERR);
- break;
- case 14: /* end of program */
- if(gettyp() == ERR || getfld() == ERR) return (ERR);
- inrem = 0; /* force byte boundary */
- break;
- case 15: /* end of file */
- inrem = 0; /* force byte boundary */
- }
- return (item);
- }
-
- gettyp() {
- if(!getbits(2)) return (ERR); /* get 2-bit field type */
- return (type = field);
- }
-
- getfld() { /* get type and value of field */
- int low;
- if(!getbits(8)) return (ERR); /* get first 8 bits */
- low = field; /* save as low order byte */
- if(!getbits(8)) return (ERR); /* get next 8 bits */
- field = (field << 8) | low; /* combine high & low bytes */
- return (item);
- }
-
- getsym() { /* get symbol */
- int i, save; char *cp;
- cp = symbol;
- save = field; /* save field */
- if(!getbits(3)) return (ERR); /* get 3-bit symbol length */
- i = field; /* capture symbol length */
- while(i--) {
- if(!getbits(8)) return (ERR); /* get next byte */
- *cp++ = field;
- }
- *cp = NULL; /* terminate symbol */
- field = save; /* restore field */
- return (item);
- }
-
- /*
- ** get next n bits from REL file into "field"
- ** return true on success, false on error
- */
- getbits(n) int n; {
- int get;
- field = 0; /* initialize result */
- while(n) { /* more bits to fetch */
- if(inrem == 0) { /* need another chunk */
- if(read(inrel, &inchunk, 1) != 1) { /* get next bit cluster */
- fputs("\n\7- Abnormal End of REL File\n", stdout);
- return (NO); /* failure */
- }
- inrem = 8; /* 8 bits remaim */
- }
- if(n > inrem) get = inrem; else get = n; /* how many from this chunk */
- n -= get; /* decrement bits needed */
- inrem -= get; /* decr remaining bits */
- field = (field << get) +
- ((inchunk >> inrem) & ~(ONES << get));
- }
- return (YES);
- }
- r remaining bits */
- field = (field << get) +
- ((inchunk >> inrem) & ~(ONES <<