xref: /inferno-os/utils/libmach/iobj.c (revision a93f6c888f6d530420fbb54e2f7fa4572cdc5208)
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