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