1 /* 2 * 8obj.c - identify and parse a 386 object file 3 */ 4 #include <lib9.h> 5 #include <bio.h> 6 #include "8c/8.out.h" 7 #include "obj.h" 8 9 typedef struct Addr Addr; 10 struct Addr 11 { 12 char sym; 13 char flags; 14 }; 15 static Addr addr(Biobuf*); 16 static char type2char(int); 17 static void skip(Biobuf*, int); 18 19 int 20 _is8(char *t) 21 { 22 uchar *s = (uchar*)t; 23 24 return s[0] == (ANAME&0xff) /* aslo = ANAME */ 25 && s[1] == ((ANAME>>8)&0xff) 26 && s[2] == D_FILE /* type */ 27 && s[3] == 1 /* sym */ 28 && s[4] == '<'; /* name of file */ 29 } 30 31 int 32 _read8(Biobuf *bp, Prog* p) 33 { 34 int as, n, c; 35 Addr a; 36 37 as = Bgetc(bp); /* as(low) */ 38 if(as < 0) 39 return 0; 40 c = Bgetc(bp); /* as(high) */ 41 if(c < 0) 42 return 0; 43 as |= ((c & 0xff) << 8); 44 p->kind = aNone; 45 if(as == ANAME || as == ASIGNAME){ 46 if(as == ASIGNAME) 47 skip(bp, 4); /* signature */ 48 p->kind = aName; 49 p->type = type2char(Bgetc(bp)); /* type */ 50 p->sym = Bgetc(bp); /* sym */ 51 n = 0; 52 for(;;) { 53 as = Bgetc(bp); 54 if(as < 0) 55 return 0; 56 n++; 57 if(as == 0) 58 break; 59 } 60 p->id = malloc(n); 61 if(p->id == 0) 62 return 0; 63 Bseek(bp, -n, 1); 64 if(Bread(bp, p->id, n) != n) 65 return 0; 66 return 1; 67 } 68 if(as == ATEXT) 69 p->kind = aText; 70 if(as == AGLOBL) 71 p->kind = aData; 72 skip(bp, 4); /* lineno(4) */ 73 a = addr(bp); 74 addr(bp); 75 if(!(a.flags & T_SYM)) 76 p->kind = aNone; 77 p->sym = a.sym; 78 return 1; 79 } 80 81 static Addr 82 addr(Biobuf *bp) 83 { 84 Addr a; 85 int t; 86 long off; 87 88 off = 0; 89 a.sym = -1; 90 a.flags = Bgetc(bp); /* flags */ 91 if(a.flags & T_INDEX) 92 skip(bp, 2); 93 if(a.flags & T_OFFSET){ 94 off = Bgetc(bp); 95 off |= Bgetc(bp) << 8; 96 off |= Bgetc(bp) << 16; 97 off |= Bgetc(bp) << 24; 98 if(off < 0) 99 off = -off; 100 } 101 if(a.flags & T_SYM) 102 a.sym = Bgetc(bp); 103 if(a.flags & T_FCONST) 104 skip(bp, 8); 105 else 106 if(a.flags & T_SCONST) 107 skip(bp, NSNAME); 108 if(a.flags & T_TYPE) { 109 t = Bgetc(bp); 110 if(a.sym > 0 && (t==D_PARAM || t==D_AUTO)) 111 _offset(a.sym, off); 112 } 113 return a; 114 } 115 116 static char 117 type2char(int t) 118 { 119 switch(t){ 120 case D_EXTERN: return 'U'; 121 case D_STATIC: return 'b'; 122 case D_AUTO: return 'a'; 123 case D_PARAM: return 'p'; 124 default: return UNKNOWN; 125 } 126 } 127 128 static void 129 skip(Biobuf *bp, int n) 130 { 131 while (n-- > 0) 132 Bgetc(bp); 133 } 134