/* ** getrel -- read a relocatable-object file */ #include #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); }