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