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