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