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