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