xref: /plan9/sys/src/libmach/6obj.c (revision 0c547597109109560d53d0e274a258f0150779c4)
1b0dcc5a8SDavid du Colombier /*
2b0dcc5a8SDavid du Colombier  * 6obj.c - identify and parse an amd64 object file
3b0dcc5a8SDavid du Colombier  */
4b0dcc5a8SDavid du Colombier #include <u.h>
5b0dcc5a8SDavid du Colombier #include <libc.h>
6b0dcc5a8SDavid du Colombier #include <bio.h>
7*0c547597SDavid du Colombier #include <mach.h>
8b0dcc5a8SDavid du Colombier #include "6c/6.out.h"
9b0dcc5a8SDavid du Colombier #include "obj.h"
10b0dcc5a8SDavid du Colombier 
11b0dcc5a8SDavid du Colombier typedef struct Addr	Addr;
12b0dcc5a8SDavid du Colombier struct Addr
13b0dcc5a8SDavid du Colombier {
14b0dcc5a8SDavid du Colombier 	char	sym;
15b0dcc5a8SDavid du Colombier 	char	flags;
16b0dcc5a8SDavid du Colombier };
17b0dcc5a8SDavid du Colombier static	Addr	addr(Biobuf*);
18b0dcc5a8SDavid du Colombier static	char	type2char(int);
19b0dcc5a8SDavid du Colombier static	void	skip(Biobuf*, int);
20b0dcc5a8SDavid du Colombier 
21b0dcc5a8SDavid du Colombier int
_is6(char * t)22b0dcc5a8SDavid du Colombier _is6(char *t)
23b0dcc5a8SDavid du Colombier {
24b0dcc5a8SDavid du Colombier 	uchar *s = (uchar*)t;
25b0dcc5a8SDavid du Colombier 
26b0dcc5a8SDavid du Colombier 	return  s[0] == (ANAME&0xff)			/* aslo = ANAME */
27b0dcc5a8SDavid du Colombier 		&& s[1] == ((ANAME>>8)&0xff)
28b0dcc5a8SDavid du Colombier 		&& s[2] == D_FILE			/* type */
29b0dcc5a8SDavid du Colombier 		&& s[3] == 1				/* sym */
30b0dcc5a8SDavid du Colombier 		&& s[4] == '<';				/* name of file */
31b0dcc5a8SDavid du Colombier }
32b0dcc5a8SDavid du Colombier 
33b0dcc5a8SDavid du Colombier int
_read6(Biobuf * bp,Prog * p)34b0dcc5a8SDavid du Colombier _read6(Biobuf *bp, Prog* p)
35b0dcc5a8SDavid du Colombier {
36b0dcc5a8SDavid du Colombier 	int as, n, c;
37b0dcc5a8SDavid du Colombier 	Addr a;
38b0dcc5a8SDavid du Colombier 
39b0dcc5a8SDavid du Colombier 	as = Bgetc(bp);		/* as(low) */
40b0dcc5a8SDavid du Colombier 	if(as < 0)
41b0dcc5a8SDavid du Colombier 		return 0;
42b0dcc5a8SDavid du Colombier 	c = Bgetc(bp);		/* as(high) */
43b0dcc5a8SDavid du Colombier 	if(c < 0)
44b0dcc5a8SDavid du Colombier 		return 0;
45b0dcc5a8SDavid du Colombier 	as |= ((c & 0xff) << 8);
46b0dcc5a8SDavid du Colombier 	p->kind = aNone;
47*0c547597SDavid du Colombier 	p->sig = 0;
48b0dcc5a8SDavid du Colombier 	if(as == ANAME || as == ASIGNAME){
49*0c547597SDavid du Colombier 		if(as == ASIGNAME){
50*0c547597SDavid du Colombier 			Bread(bp, &p->sig, 4);
51*0c547597SDavid du Colombier 			p->sig = leswal(p->sig);
52*0c547597SDavid du Colombier 		}
53b0dcc5a8SDavid du Colombier 		p->kind = aName;
54b0dcc5a8SDavid du Colombier 		p->type = type2char(Bgetc(bp));		/* type */
55b0dcc5a8SDavid du Colombier 		p->sym = Bgetc(bp);			/* sym */
56b0dcc5a8SDavid du Colombier 		n = 0;
57b0dcc5a8SDavid du Colombier 		for(;;) {
58b0dcc5a8SDavid du Colombier 			as = Bgetc(bp);
59b0dcc5a8SDavid du Colombier 			if(as < 0)
60b0dcc5a8SDavid du Colombier 				return 0;
61b0dcc5a8SDavid du Colombier 			n++;
62b0dcc5a8SDavid du Colombier 			if(as == 0)
63b0dcc5a8SDavid du Colombier 				break;
64b0dcc5a8SDavid du Colombier 		}
65b0dcc5a8SDavid du Colombier 		p->id = malloc(n);
66b0dcc5a8SDavid du Colombier 		if(p->id == 0)
67b0dcc5a8SDavid du Colombier 			return 0;
68b0dcc5a8SDavid du Colombier 		Bseek(bp, -n, 1);
69b0dcc5a8SDavid du Colombier 		if(Bread(bp, p->id, n) != n)
70b0dcc5a8SDavid du Colombier 			return 0;
71b0dcc5a8SDavid du Colombier 		return 1;
72b0dcc5a8SDavid du Colombier 	}
73b0dcc5a8SDavid du Colombier 	if(as == ATEXT)
74b0dcc5a8SDavid du Colombier 		p->kind = aText;
75b0dcc5a8SDavid du Colombier 	if(as == AGLOBL)
76b0dcc5a8SDavid du Colombier 		p->kind = aData;
77b0dcc5a8SDavid du Colombier 	skip(bp, 4);		/* lineno(4) */
78b0dcc5a8SDavid du Colombier 	a = addr(bp);
79b0dcc5a8SDavid du Colombier 	addr(bp);
80b0dcc5a8SDavid du Colombier 	if(!(a.flags & T_SYM))
81b0dcc5a8SDavid du Colombier 		p->kind = aNone;
82b0dcc5a8SDavid du Colombier 	p->sym = a.sym;
83b0dcc5a8SDavid du Colombier 	return 1;
84b0dcc5a8SDavid du Colombier }
85b0dcc5a8SDavid du Colombier 
86b0dcc5a8SDavid du Colombier static Addr
addr(Biobuf * bp)87b0dcc5a8SDavid du Colombier addr(Biobuf *bp)
88b0dcc5a8SDavid du Colombier {
89b0dcc5a8SDavid du Colombier 	Addr a;
90b0dcc5a8SDavid du Colombier 	int t;
91b0dcc5a8SDavid du Colombier 	long l;
92b0dcc5a8SDavid du Colombier 	vlong off;
93b0dcc5a8SDavid du Colombier 
94b0dcc5a8SDavid du Colombier 	off = 0;
95b0dcc5a8SDavid du Colombier 	a.sym = -1;
96b0dcc5a8SDavid du Colombier 	a.flags = Bgetc(bp);			/* flags */
97b0dcc5a8SDavid du Colombier 	if(a.flags & T_INDEX)
98b0dcc5a8SDavid du Colombier 		skip(bp, 2);
99b0dcc5a8SDavid du Colombier 	if(a.flags & T_OFFSET){
100b0dcc5a8SDavid du Colombier 		l = Bgetc(bp);
101b0dcc5a8SDavid du Colombier 		l |= Bgetc(bp) << 8;
102b0dcc5a8SDavid du Colombier 		l |= Bgetc(bp) << 16;
103b0dcc5a8SDavid du Colombier 		l |= Bgetc(bp) << 24;
104b0dcc5a8SDavid du Colombier 		off = l;
105b0dcc5a8SDavid du Colombier 		if(a.flags & T_64){
106b0dcc5a8SDavid du Colombier 			l = Bgetc(bp);
107b0dcc5a8SDavid du Colombier 			l |= Bgetc(bp) << 8;
108b0dcc5a8SDavid du Colombier 			l |= Bgetc(bp) << 16;
109b0dcc5a8SDavid du Colombier 			l |= Bgetc(bp) << 24;
110b0dcc5a8SDavid du Colombier 			off = ((vlong)l << 32) | (off & 0xFFFFFFFF);
111b0dcc5a8SDavid du Colombier 		}
112b0dcc5a8SDavid du Colombier 		if(off < 0)
113b0dcc5a8SDavid du Colombier 			off = -off;
114b0dcc5a8SDavid du Colombier 	}
115b0dcc5a8SDavid du Colombier 	if(a.flags & T_SYM)
116b0dcc5a8SDavid du Colombier 		a.sym = Bgetc(bp);
117b0dcc5a8SDavid du Colombier 	if(a.flags & T_FCONST)
118b0dcc5a8SDavid du Colombier 		skip(bp, 8);
119b0dcc5a8SDavid du Colombier 	else
120b0dcc5a8SDavid du Colombier 	if(a.flags & T_SCONST)
121b0dcc5a8SDavid du Colombier 		skip(bp, NSNAME);
122b0dcc5a8SDavid du Colombier 	if(a.flags & T_TYPE) {
123b0dcc5a8SDavid du Colombier 		t = Bgetc(bp);
124b0dcc5a8SDavid du Colombier 		if(a.sym > 0 && (t==D_PARAM || t==D_AUTO))
125b0dcc5a8SDavid du Colombier 			_offset(a.sym, off);
126b0dcc5a8SDavid du Colombier 	}
127b0dcc5a8SDavid du Colombier 	return a;
128b0dcc5a8SDavid du Colombier }
129b0dcc5a8SDavid du Colombier 
130b0dcc5a8SDavid du Colombier static char
type2char(int t)131b0dcc5a8SDavid du Colombier type2char(int t)
132b0dcc5a8SDavid du Colombier {
133b0dcc5a8SDavid du Colombier 	switch(t){
134b0dcc5a8SDavid du Colombier 	case D_EXTERN:		return 'U';
135b0dcc5a8SDavid du Colombier 	case D_STATIC:		return 'b';
136b0dcc5a8SDavid du Colombier 	case D_AUTO:		return 'a';
137b0dcc5a8SDavid du Colombier 	case D_PARAM:		return 'p';
138b0dcc5a8SDavid du Colombier 	default:		return UNKNOWN;
139b0dcc5a8SDavid du Colombier 	}
140b0dcc5a8SDavid du Colombier }
141b0dcc5a8SDavid du Colombier 
142b0dcc5a8SDavid du Colombier static void
skip(Biobuf * bp,int n)143b0dcc5a8SDavid du Colombier skip(Biobuf *bp, int n)
144b0dcc5a8SDavid du Colombier {
145b0dcc5a8SDavid du Colombier 	while (n-- > 0)
146b0dcc5a8SDavid du Colombier 		Bgetc(bp);
147b0dcc5a8SDavid du Colombier }
148