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