1 /* 2 * 5obj.c - identify and parse an arm object file 3 */ 4 #include <u.h> 5 #include <libc.h> 6 #include <bio.h> 7 #include <mach.h> 8 #include "5c/5.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 _is5(char *s) 24 { 25 return s[0] == ANAME /* ANAME */ 26 && s[1] == D_FILE /* type */ 27 && s[2] == 1 /* sym */ 28 && s[3] == '<'; /* name of file */ 29 } 30 31 int 32 _read5(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 p->sig = 0; 42 if(as == ANAME || as == ASIGNAME){ 43 if(as == ASIGNAME){ 44 Bread(bp, &p->sig, 4); 45 p->sig = leswal(p->sig); 46 } 47 p->kind = aName; 48 p->type = type2char(Bgetc(bp)); /* type */ 49 p->sym = Bgetc(bp); /* sym */ 50 n = 0; 51 for(;;) { 52 as = Bgetc(bp); 53 if(as < 0) 54 return 0; 55 n++; 56 if(as == 0) 57 break; 58 } 59 p->id = malloc(n); 60 if(p->id == 0) 61 return 0; 62 Bseek(bp, -n, 1); 63 if(Bread(bp, p->id, n) != n) 64 return 0; 65 return 1; 66 } 67 if(as == ATEXT) 68 p->kind = aText; 69 else if(as == AGLOBL) 70 p->kind = aData; 71 skip(bp, 6); /* scond(1), reg(1), lineno(4) */ 72 a = addr(bp); 73 addr(bp); 74 if(a.type != D_OREG || a.name != D_STATIC && a.name != D_EXTERN) 75 p->kind = aNone; 76 p->sym = a.sym; 77 return 1; 78 } 79 80 static Addr 81 addr(Biobuf *bp) 82 { 83 Addr a; 84 long off; 85 86 a.type = Bgetc(bp); /* a.type */ 87 skip(bp,1); /* reg */ 88 a.sym = Bgetc(bp); /* sym index */ 89 a.name = Bgetc(bp); /* sym type */ 90 switch(a.type){ 91 default: 92 case D_NONE: 93 case D_REG: 94 case D_FREG: 95 case D_PSR: 96 case D_FPCR: 97 break; 98 case D_OREG: 99 case D_CONST: 100 case D_BRANCH: 101 case D_SHIFT: 102 off = Bgetc(bp); 103 off |= Bgetc(bp) << 8; 104 off |= Bgetc(bp) << 16; 105 off |= Bgetc(bp) << 24; 106 if(off < 0) 107 off = -off; 108 if(a.sym && (a.name==D_PARAM || a.name==D_AUTO)) 109 _offset(a.sym, off); 110 break; 111 case D_SCONST: 112 skip(bp, NSNAME); 113 break; 114 case D_FCONST: 115 skip(bp, 8); 116 break; 117 } 118 return a; 119 } 120 121 static char 122 type2char(int t) 123 { 124 switch(t){ 125 case D_EXTERN: return 'U'; 126 case D_STATIC: return 'b'; 127 case D_AUTO: return 'a'; 128 case D_PARAM: return 'p'; 129 default: return UNKNOWN; 130 } 131 } 132 133 static void 134 skip(Biobuf *bp, int n) 135 { 136 while (n-- > 0) 137 Bgetc(bp); 138 } 139