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