1 // Inferno libmach/6obj.c
2 // http://code.google.com/p/inferno-os/source/browse/utils/libmach/6obj.c
3 //
4 // Copyright © 1994-1999 Lucent Technologies Inc.
5 // Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
6 // Portions Copyright © 1997-1999 Vita Nuova Limited.
7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
8 // Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
9 // Portions Copyright © 2009 The Go Authors. All rights reserved.
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28
29 /*
30 * 6obj.c - identify and parse an amd64 object file
31 */
32 #include <u.h>
33 #include <libc.h>
34 #include <bio.h>
35 #include <mach.h>
36 #include "../cmd/6l/6.out.h"
37 #include "obj.h"
38
39 typedef struct Addr Addr;
40 struct Addr
41 {
42 char sym;
43 char flags;
44 char gotype;
45 };
46 static Addr addr(Biobuf*);
47 static char type2char(int);
48 static void skip(Biobuf*, int);
49
50 int
51 _is6(char *t)
52 {
53 uchar *s = (uchar*)t;
54
55 return s[0] == (ANAME&0xff) /* aslo = ANAME */
56 && s[1] == ((ANAME>>8)&0xff)
57 && s[2] == D_FILE /* type */
58 && s[3] == 1 /* sym */
59 && s[4] == '<'; /* name of file */
60 }
61
62 int
63 _read6(Biobuf *bp, Prog* p)
64 {
65 int as, n, c;
66 Addr a;
67
68 as = Bgetc(bp); /* as(low) */
69 if(as < 0)
70 return 0;
71 c = Bgetc(bp); /* as(high) */
72 if(c < 0)
73 return 0;
74 as |= ((c & 0xff) << 8);
75 p->kind = aNone;
76 p->sig = 0;
77 if(as == ANAME || as == ASIGNAME){
78 if(as == ASIGNAME){
79 Bread(bp, &p->sig, 4);
80 p->sig = leswal(p->sig);
81 }
82 p->kind = aName;
83 p->type = type2char(Bgetc(bp)); /* type */
84 p->sym = Bgetc(bp); /* sym */
85 n = 0;
86 for(;;) {
87 as = Bgetc(bp);
88 if(as < 0)
89 return 0;
90 n++;
91 if(as == 0)
92 break;
93 }
94 p->id = malloc(n);
95 if(p->id == 0)
96 return 0;
97 Bseek(bp, -n, 1);
98 if(Bread(bp, p->id, n) != n)
99 return 0;
100 return 1;
101 }
102 if(as == ATEXT)
103 p->kind = aText;
104 if(as == AGLOBL)
105 p->kind = aData;
106 skip(bp, 4); /* lineno(4) */
107 a = addr(bp);
108 addr(bp);
109 if(!(a.flags & T_SYM))
110 p->kind = aNone;
111 p->sym = a.sym;
112 return 1;
113 }
114
115 static Addr
116 addr(Biobuf *bp)
117 {
118 Addr a;
119 int t;
120 int32 l;
121 vlong off;
122
123 off = 0;
124 a.sym = -1;
125 a.flags = Bgetc(bp); /* flags */
126 a.gotype = 0;
127 if(a.flags & T_INDEX)
128 skip(bp, 2);
129 if(a.flags & T_OFFSET){
130 l = Bgetc(bp);
131 l |= Bgetc(bp) << 8;
132 l |= Bgetc(bp) << 16;
133 l |= Bgetc(bp) << 24;
134 off = l;
135 if(a.flags & T_64){
136 l = Bgetc(bp);
137 l |= Bgetc(bp) << 8;
138 l |= Bgetc(bp) << 16;
139 l |= Bgetc(bp) << 24;
140 off = ((vlong)l << 32) | (off & 0xFFFFFFFF);
141 }
142 if(off < 0)
143 off = -off;
144 }
145 if(a.flags & T_SYM)
146 a.sym = Bgetc(bp);
147 if(a.flags & T_FCONST)
148 skip(bp, 8);
149 else
150 if(a.flags & T_SCONST)
151 skip(bp, NSNAME);
152 if(a.flags & T_TYPE) {
153 t = Bgetc(bp);
154 if(a.sym > 0 && (t==D_PARAM || t==D_AUTO))
155 _offset(a.sym, off);
156 }
157 if(a.flags & T_GOTYPE)
158 a.gotype = Bgetc(bp);
159 return a;
160 }
161
162 static char
163 type2char(int t)
164 {
165 switch(t){
166 case D_EXTERN: return 'U';
167 case D_STATIC: return 'b';
168 case D_AUTO: return 'a';
169 case D_PARAM: return 'p';
170 default: return UNKNOWN;
171 }
172 }
173
174 static void
175 skip(Biobuf *bp, int n)
176 {
177 while (n-- > 0)
178 Bgetc(bp);
179 }