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