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