1 /* 2 * 6obj.c - identify and parse an amd64 object file 3 */ 4 #include <lib9.h> 5 #include <bio.h> 6 #include <mach.h> 7 #include "6c/6.out.h" 8 #include "obj.h" 9 10 typedef struct Addr Addr; 11 struct Addr 12 { 13 char sym; 14 char flags; 15 }; 16 static Addr addr(Biobuf*); 17 static char type2char(int); 18 static void skip(Biobuf*, int); 19 20 int 21 _is6(char *t) 22 { 23 uchar *s = (uchar*)t; 24 25 return s[0] == (ANAME&0xff) /* aslo = ANAME */ 26 && s[1] == ((ANAME>>8)&0xff) 27 && s[2] == D_FILE /* type */ 28 && s[3] == 1 /* sym */ 29 && s[4] == '<'; /* name of file */ 30 } 31 32 int 33 _read6(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 = leswal(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 if(as == AGLOBL) 75 p->kind = aData; 76 skip(bp, 4); /* lineno(4) */ 77 a = addr(bp); 78 addr(bp); 79 if(!(a.flags & T_SYM)) 80 p->kind = aNone; 81 p->sym = a.sym; 82 return 1; 83 } 84 85 static Addr 86 addr(Biobuf *bp) 87 { 88 Addr a; 89 int t; 90 long l; 91 vlong off; 92 93 off = 0; 94 a.sym = -1; 95 a.flags = Bgetc(bp); /* flags */ 96 if(a.flags & T_INDEX) 97 skip(bp, 2); 98 if(a.flags & T_OFFSET){ 99 l = Bgetc(bp); 100 l |= Bgetc(bp) << 8; 101 l |= Bgetc(bp) << 16; 102 l |= Bgetc(bp) << 24; 103 off = l; 104 if(a.flags & T_64){ 105 l = Bgetc(bp); 106 l |= Bgetc(bp) << 8; 107 l |= Bgetc(bp) << 16; 108 l |= Bgetc(bp) << 24; 109 off = ((vlong)l << 32) | (off & 0xFFFFFFFF); 110 } 111 if(off < 0) 112 off = -off; 113 } 114 if(a.flags & T_SYM) 115 a.sym = Bgetc(bp); 116 if(a.flags & T_FCONST) 117 skip(bp, 8); 118 else 119 if(a.flags & T_SCONST) 120 skip(bp, NSNAME); 121 if(a.flags & T_TYPE) { 122 t = Bgetc(bp); 123 if(a.sym > 0 && (t==D_PARAM || t==D_AUTO)) 124 _offset(a.sym, off); 125 } 126 return a; 127 } 128 129 static char 130 type2char(int t) 131 { 132 switch(t){ 133 case D_EXTERN: return 'U'; 134 case D_STATIC: return 'b'; 135 case D_AUTO: return 'a'; 136 case D_PARAM: return 'p'; 137 default: return UNKNOWN; 138 } 139 } 140 141 static void 142 skip(Biobuf *bp, int n) 143 { 144 while (n-- > 0) 145 Bgetc(bp); 146 } 147