1 /* 2 * qobj.c - identify and parse a PowerPC object file 3 * forsyth@plan9.cs.york.ac.uk 4 */ 5 #include <u.h> 6 #include <libc.h> 7 #include <bio.h> 8 #include "qc/q.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 int 23 _isq(char *s) 24 { 25 return (s[0]&0377) == ANAME /* ANAME */ 26 && s[1] == D_FILE /* type */ 27 && s[2] == 1 /* sym */ 28 && s[3] == '<'; /* name of file */ 29 } 30 31 int 32 _readq(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 else if(as == AGLOBL) 65 p->kind = aData; 66 n = Bgetc(bp); /* reg and flag */ 67 skip(bp, 4); /* lineno(4) */ 68 a = addr(bp); 69 if(n & 0x40) 70 addr(bp); 71 addr(bp); 72 if(a.type != D_OREG || a.name != D_STATIC && a.name != D_EXTERN) 73 p->kind = aNone; 74 p->sym = a.sym; 75 return 1; 76 } 77 78 static Addr 79 addr(Biobuf *bp) 80 { 81 Addr a; 82 long off; 83 84 a.type = Bgetc(bp); /* a.type */ 85 skip(bp,1); /* reg */ 86 a.sym = Bgetc(bp); /* sym index */ 87 a.name = Bgetc(bp); /* sym type */ 88 switch(a.type){ 89 default: 90 case D_NONE: case D_REG: case D_FREG: case D_CREG: 91 case D_FPSCR: case D_MSR: case D_SREG: 92 break; 93 case D_SPR: 94 case D_OREG: 95 case D_CONST: 96 case D_BRANCH: 97 off = Bgetc(bp); 98 off |= Bgetc(bp) << 8; 99 off |= Bgetc(bp) << 16; 100 off |= Bgetc(bp) << 24; 101 if(off < 0) 102 off = -off; 103 if(a.sym && (a.name==D_PARAM || a.name==D_AUTO)) 104 _offset(a.sym, off); 105 break; 106 case D_SCONST: 107 skip(bp, NSNAME); 108 break; 109 case D_FCONST: 110 skip(bp, 8); 111 break; 112 } 113 return a; 114 } 115 116 static char 117 type2char(int t) 118 { 119 switch(t){ 120 case D_EXTERN: return 'U'; 121 case D_STATIC: return 'b'; 122 case D_AUTO: return 'a'; 123 case D_PARAM: return 'p'; 124 default: return UNKNOWN; 125 } 126 } 127 128 static void 129 skip(Biobuf *bp, int n) 130 { 131 while (n-- > 0) 132 Bgetc(bp); 133 } 134