13e12c5d1SDavid du Colombier /* 2bd389b36SDavid du Colombier * 8obj.c - identify and parse a 386 object file 33e12c5d1SDavid du Colombier */ 43e12c5d1SDavid du Colombier #include <u.h> 53e12c5d1SDavid du Colombier #include <libc.h> 63e12c5d1SDavid du Colombier #include <bio.h> 73e12c5d1SDavid du Colombier #include "8c/8.out.h" 83e12c5d1SDavid du Colombier #include "obj.h" 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier typedef struct Addr Addr; 113e12c5d1SDavid du Colombier struct Addr 123e12c5d1SDavid du Colombier { 133e12c5d1SDavid du Colombier char sym; 143e12c5d1SDavid du Colombier char flags; 153e12c5d1SDavid du Colombier }; 16bd389b36SDavid du Colombier static Addr addr(Biobuf*); 173e12c5d1SDavid du Colombier static char type2char(int); 18bd389b36SDavid du Colombier static void skip(Biobuf*, int); 193e12c5d1SDavid du Colombier 203e12c5d1SDavid du Colombier int 213e12c5d1SDavid du Colombier _is8(char *t) 223e12c5d1SDavid du Colombier { 233e12c5d1SDavid du Colombier uchar *s = (uchar*)t; 243e12c5d1SDavid du Colombier 253e12c5d1SDavid du Colombier return s[0] == (ANAME&0xff) /* aslo = ANAME */ 263e12c5d1SDavid du Colombier && s[1] == ((ANAME>>8)&0xff) 273e12c5d1SDavid du Colombier && s[2] == D_FILE /* type */ 283e12c5d1SDavid du Colombier && s[3] == 1 /* sym */ 293e12c5d1SDavid du Colombier && s[4] == '<'; /* name of file */ 303e12c5d1SDavid du Colombier } 313e12c5d1SDavid du Colombier 32bd389b36SDavid du Colombier int 33bd389b36SDavid du Colombier _read8(Biobuf *bp, Prog* p) 343e12c5d1SDavid du Colombier { 35*219b2ee8SDavid du Colombier int as, n, c; 363e12c5d1SDavid du Colombier Addr a; 373e12c5d1SDavid du Colombier 38bd389b36SDavid du Colombier as = Bgetc(bp); /* as(low) */ 393e12c5d1SDavid du Colombier if(as < 0) 403e12c5d1SDavid du Colombier return 0; 41bd389b36SDavid du Colombier c = Bgetc(bp); /* as(high) */ 423e12c5d1SDavid du Colombier if(c < 0) 433e12c5d1SDavid du Colombier return 0; 443e12c5d1SDavid du Colombier as |= ((c & 0xff) << 8); 453e12c5d1SDavid du Colombier p->kind = aNone; 463e12c5d1SDavid du Colombier if(as == ANAME){ 473e12c5d1SDavid du Colombier p->kind = aName; 48bd389b36SDavid du Colombier p->type = type2char(Bgetc(bp)); /* type */ 49bd389b36SDavid du Colombier p->sym = Bgetc(bp); /* sym */ 50*219b2ee8SDavid du Colombier n = 0; 51*219b2ee8SDavid du Colombier for(;;) { 52*219b2ee8SDavid du Colombier as = Bgetc(bp); 53*219b2ee8SDavid du Colombier if(as < 0) 54*219b2ee8SDavid du Colombier return 0; 55*219b2ee8SDavid du Colombier n++; 56*219b2ee8SDavid du Colombier if(as == 0) 57*219b2ee8SDavid du Colombier break; 583e12c5d1SDavid du Colombier } 59*219b2ee8SDavid du Colombier p->id = malloc(n); 60*219b2ee8SDavid du Colombier if(p->id == 0) 61*219b2ee8SDavid du Colombier return 0; 62*219b2ee8SDavid du Colombier Bseek(bp, -n, 1); 63*219b2ee8SDavid du Colombier if(Bread(bp, p->id, n) != n) 64*219b2ee8SDavid du Colombier return 0; 65bd389b36SDavid du Colombier return 1; 663e12c5d1SDavid du Colombier } 673e12c5d1SDavid du Colombier if(as == ATEXT) 683e12c5d1SDavid du Colombier p->kind = aText; 693e12c5d1SDavid du Colombier if(as == AGLOBL) 703e12c5d1SDavid du Colombier p->kind = aData; 71bd389b36SDavid du Colombier skip(bp, 4); /* lineno(4) */ 72bd389b36SDavid du Colombier a = addr(bp); 73bd389b36SDavid du Colombier addr(bp); 743e12c5d1SDavid du Colombier if(!(a.flags & T_SYM)) 753e12c5d1SDavid du Colombier p->kind = aNone; 763e12c5d1SDavid du Colombier p->sym = a.sym; 77bd389b36SDavid du Colombier return 1; 783e12c5d1SDavid du Colombier } 793e12c5d1SDavid du Colombier 803e12c5d1SDavid du Colombier static Addr 81bd389b36SDavid du Colombier addr(Biobuf *bp) 823e12c5d1SDavid du Colombier { 833e12c5d1SDavid du Colombier Addr a; 84bd389b36SDavid du Colombier int t; 853e12c5d1SDavid du Colombier long off; 863e12c5d1SDavid du Colombier 873e12c5d1SDavid du Colombier off = 0; 88bd389b36SDavid du Colombier a.sym = -1; 89bd389b36SDavid du Colombier a.flags = Bgetc(bp); /* flags */ 90bd389b36SDavid du Colombier if(a.flags & T_INDEX) 91bd389b36SDavid du Colombier skip(bp, 2); 923e12c5d1SDavid du Colombier if(a.flags & T_OFFSET){ 93bd389b36SDavid du Colombier off = Bgetc(bp); 94bd389b36SDavid du Colombier off |= Bgetc(bp) << 8; 95bd389b36SDavid du Colombier off |= Bgetc(bp) << 16; 96bd389b36SDavid du Colombier off |= Bgetc(bp) << 24; 973e12c5d1SDavid du Colombier if(off < 0) 983e12c5d1SDavid du Colombier off = -off; 993e12c5d1SDavid du Colombier } 1003e12c5d1SDavid du Colombier if(a.flags & T_SYM) 101bd389b36SDavid du Colombier a.sym = Bgetc(bp); 1023e12c5d1SDavid du Colombier if(a.flags & T_FCONST) 103bd389b36SDavid du Colombier skip(bp, 8); 1043e12c5d1SDavid du Colombier else 1053e12c5d1SDavid du Colombier if(a.flags & T_SCONST) 106bd389b36SDavid du Colombier skip(bp, NSNAME); 107bd389b36SDavid du Colombier if(a.flags & T_TYPE) { 108bd389b36SDavid du Colombier t = Bgetc(bp); 1093e12c5d1SDavid du Colombier if(a.sym > 0 && (t==D_PARAM || t==D_AUTO)) 110bd389b36SDavid du Colombier _offset(a.sym, off); 111bd389b36SDavid du Colombier } 1123e12c5d1SDavid du Colombier return a; 1133e12c5d1SDavid du Colombier } 1143e12c5d1SDavid du Colombier 1153e12c5d1SDavid du Colombier static char 1163e12c5d1SDavid du Colombier type2char(int t) 1173e12c5d1SDavid du Colombier { 1183e12c5d1SDavid du Colombier switch(t){ 1193e12c5d1SDavid du Colombier case D_EXTERN: return 'U'; 1203e12c5d1SDavid du Colombier case D_STATIC: return 'b'; 1213e12c5d1SDavid du Colombier case D_AUTO: return 'a'; 1223e12c5d1SDavid du Colombier case D_PARAM: return 'p'; 1233e12c5d1SDavid du Colombier default: return UNKNOWN; 1243e12c5d1SDavid du Colombier } 1253e12c5d1SDavid du Colombier } 126bd389b36SDavid du Colombier 127bd389b36SDavid du Colombier static void 128bd389b36SDavid du Colombier skip(Biobuf *bp, int n) 129bd389b36SDavid du Colombier { 130bd389b36SDavid du Colombier while (n-- > 0) 131bd389b36SDavid du Colombier Bgetc(bp); 132bd389b36SDavid du Colombier } 133