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