1 /* 2 * 6obj.c - identify and parse an amd64 object file 3 */ 4 #include <u.h> 5 #include <libc.h> 6 #include <bio.h> 7 #include <mach.h> 8 #include "6c/6.out.h" 9 #include "obj.h" 10 11 typedef struct Addr Addr; 12 struct Addr 13 { 14 char sym; 15 char flags; 16 }; 17 static Addr addr(Biobuf*); 18 static char type2char(int); 19 static void skip(Biobuf*, int); 20 21 int 22 _is6(char *t) 23 { 24 uchar *s = (uchar*)t; 25 26 return s[0] == (ANAME&0xff) /* aslo = ANAME */ 27 && s[1] == ((ANAME>>8)&0xff) 28 && s[2] == D_FILE /* type */ 29 && s[3] == 1 /* sym */ 30 && s[4] == '<'; /* name of file */ 31 } 32 33 int 34 _read6(Biobuf *bp, Prog* p) 35 { 36 int as, n, c; 37 Addr a; 38 39 as = Bgetc(bp); /* as(low) */ 40 if(as < 0) 41 return 0; 42 c = Bgetc(bp); /* as(high) */ 43 if(c < 0) 44 return 0; 45 as |= ((c & 0xff) << 8); 46 p->kind = aNone; 47 p->sig = 0; 48 if(as == ANAME || as == ASIGNAME){ 49 if(as == ASIGNAME){ 50 Bread(bp, &p->sig, 4); 51 p->sig = leswal(p->sig); 52 } 53 p->kind = aName; 54 p->type = type2char(Bgetc(bp)); /* type */ 55 p->sym = Bgetc(bp); /* sym */ 56 n = 0; 57 for(;;) { 58 as = Bgetc(bp); 59 if(as < 0) 60 return 0; 61 n++; 62 if(as == 0) 63 break; 64 } 65 p->id = malloc(n); 66 if(p->id == 0) 67 return 0; 68 Bseek(bp, -n, 1); 69 if(Bread(bp, p->id, n) != n) 70 return 0; 71 return 1; 72 } 73 if(as == ATEXT) 74 p->kind = aText; 75 if(as == AGLOBL) 76 p->kind = aData; 77 skip(bp, 4); /* lineno(4) */ 78 a = addr(bp); 79 addr(bp); 80 if(!(a.flags & T_SYM)) 81 p->kind = aNone; 82 p->sym = a.sym; 83 return 1; 84 } 85 86 static Addr 87 addr(Biobuf *bp) 88 { 89 Addr a; 90 int t; 91 long l; 92 vlong off; 93 94 off = 0; 95 a.sym = -1; 96 a.flags = Bgetc(bp); /* flags */ 97 if(a.flags & T_INDEX) 98 skip(bp, 2); 99 if(a.flags & T_OFFSET){ 100 l = Bgetc(bp); 101 l |= Bgetc(bp) << 8; 102 l |= Bgetc(bp) << 16; 103 l |= Bgetc(bp) << 24; 104 off = l; 105 if(a.flags & T_64){ 106 l = Bgetc(bp); 107 l |= Bgetc(bp) << 8; 108 l |= Bgetc(bp) << 16; 109 l |= Bgetc(bp) << 24; 110 off = ((vlong)l << 32) | (off & 0xFFFFFFFF); 111 } 112 if(off < 0) 113 off = -off; 114 } 115 if(a.flags & T_SYM) 116 a.sym = Bgetc(bp); 117 if(a.flags & T_FCONST) 118 skip(bp, 8); 119 else 120 if(a.flags & T_SCONST) 121 skip(bp, NSNAME); 122 if(a.flags & T_TYPE) { 123 t = Bgetc(bp); 124 if(a.sym > 0 && (t==D_PARAM || t==D_AUTO)) 125 _offset(a.sym, off); 126 } 127 return a; 128 } 129 130 static char 131 type2char(int t) 132 { 133 switch(t){ 134 case D_EXTERN: return 'U'; 135 case D_STATIC: return 'b'; 136 case D_AUTO: return 'a'; 137 case D_PARAM: return 'p'; 138 default: return UNKNOWN; 139 } 140 } 141 142 static void 143 skip(Biobuf *bp, int n) 144 { 145 while (n-- > 0) 146 Bgetc(bp); 147 } 148