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