home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
utils
/
asmutl
/
smmaclnk.ark
/
GETREL.C
< prev
next >
Wrap
Text File
|
1987-09-10
|
4KB
|
123 lines
/*
** 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 <<