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