Blame


1 a84cbb2a 2004-04-19 devnull #include <u.h>
2 a84cbb2a 2004-04-19 devnull #include <libc.h>
3 a84cbb2a 2004-04-19 devnull #include <bio.h>
4 a84cbb2a 2004-04-19 devnull #include <mach.h>
5 a84cbb2a 2004-04-19 devnull
6 a84cbb2a 2004-04-19 devnull int machdebug = 0;
7 a84cbb2a 2004-04-19 devnull
8 a84cbb2a 2004-04-19 devnull Fhdr *fhdrlist;
9 a84cbb2a 2004-04-19 devnull static Fhdr *last;
10 a84cbb2a 2004-04-19 devnull
11 a84cbb2a 2004-04-19 devnull static void
12 a84cbb2a 2004-04-19 devnull relocsym(Symbol *dst, Symbol *src, ulong base)
13 a84cbb2a 2004-04-19 devnull {
14 a84cbb2a 2004-04-19 devnull if(dst != src)
15 a84cbb2a 2004-04-19 devnull *dst = *src;
16 a84cbb2a 2004-04-19 devnull if(dst->loc.type == LADDR)
17 a84cbb2a 2004-04-19 devnull dst->loc.addr += base;
18 a84cbb2a 2004-04-19 devnull if(dst->hiloc.type == LADDR)
19 a84cbb2a 2004-04-19 devnull dst->hiloc.addr += base;
20 a84cbb2a 2004-04-19 devnull }
21 a84cbb2a 2004-04-19 devnull
22 a84cbb2a 2004-04-19 devnull void
23 a84cbb2a 2004-04-19 devnull _addhdr(Fhdr *h)
24 a84cbb2a 2004-04-19 devnull {
25 a84cbb2a 2004-04-19 devnull h->next = nil;
26 a84cbb2a 2004-04-19 devnull if(fhdrlist == nil){
27 a84cbb2a 2004-04-19 devnull fhdrlist = h;
28 a84cbb2a 2004-04-19 devnull last = h;
29 a84cbb2a 2004-04-19 devnull }else{
30 a84cbb2a 2004-04-19 devnull last->next = h;
31 a84cbb2a 2004-04-19 devnull last = h;
32 a84cbb2a 2004-04-19 devnull }
33 a84cbb2a 2004-04-19 devnull }
34 a84cbb2a 2004-04-19 devnull
35 a84cbb2a 2004-04-19 devnull void
36 a84cbb2a 2004-04-19 devnull _delhdr(Fhdr *h)
37 a84cbb2a 2004-04-19 devnull {
38 a84cbb2a 2004-04-19 devnull Fhdr *p;
39 a84cbb2a 2004-04-19 devnull
40 a84cbb2a 2004-04-19 devnull if(h == fhdrlist)
41 a84cbb2a 2004-04-19 devnull fhdrlist = h->next;
42 a84cbb2a 2004-04-19 devnull else{
43 a84cbb2a 2004-04-19 devnull for(p=fhdrlist; p && p->next!=h; p=p->next)
44 a84cbb2a 2004-04-19 devnull ;
45 dd944ec7 2005-01-23 devnull if(p){
46 a84cbb2a 2004-04-19 devnull p->next = h->next;
47 dd944ec7 2005-01-23 devnull if(p->next == nil)
48 dd944ec7 2005-01-23 devnull last = p;
49 dd944ec7 2005-01-23 devnull }
50 a84cbb2a 2004-04-19 devnull }
51 a84cbb2a 2004-04-19 devnull h->next = nil;
52 a84cbb2a 2004-04-19 devnull }
53 a84cbb2a 2004-04-19 devnull
54 1cc215aa 2004-12-25 devnull Fhdr*
55 1cc215aa 2004-12-25 devnull findhdr(char *name)
56 1cc215aa 2004-12-25 devnull {
57 1cc215aa 2004-12-25 devnull int len, plen;
58 1cc215aa 2004-12-25 devnull Fhdr *p;
59 1cc215aa 2004-12-25 devnull
60 1cc215aa 2004-12-25 devnull len = strlen(name);
61 1cc215aa 2004-12-25 devnull for(p=fhdrlist; p; p=p->next){
62 1cc215aa 2004-12-25 devnull plen = strlen(p->filename);
63 1cc215aa 2004-12-25 devnull if(plen >= len)
64 1cc215aa 2004-12-25 devnull if(strcmp(p->filename+plen-len, name) == 0)
65 1cc215aa 2004-12-25 devnull if(plen == len || p->filename[plen-len-1] == '/')
66 1cc215aa 2004-12-25 devnull return p;
67 1cc215aa 2004-12-25 devnull }
68 1cc215aa 2004-12-25 devnull return nil;
69 1cc215aa 2004-12-25 devnull }
70 1cc215aa 2004-12-25 devnull
71 a84cbb2a 2004-04-19 devnull int
72 443d6288 2012-02-19 rsc pc2file(u64int pc, char *file, uint nfile, ulong *line)
73 a84cbb2a 2004-04-19 devnull {
74 a84cbb2a 2004-04-19 devnull Fhdr *p;
75 a84cbb2a 2004-04-19 devnull
76 a84cbb2a 2004-04-19 devnull for(p=fhdrlist; p; p=p->next)
77 a84cbb2a 2004-04-19 devnull if(p->pc2file && p->pc2file(p, pc-p->base, file, nfile, line) >= 0)
78 a84cbb2a 2004-04-19 devnull return 0;
79 a84cbb2a 2004-04-19 devnull werrstr("no source file for 0x%lux", pc);
80 a84cbb2a 2004-04-19 devnull return -1;
81 a84cbb2a 2004-04-19 devnull }
82 a84cbb2a 2004-04-19 devnull
83 a84cbb2a 2004-04-19 devnull int
84 443d6288 2012-02-19 rsc pc2line(u64int pc, ulong *line)
85 a84cbb2a 2004-04-19 devnull {
86 a84cbb2a 2004-04-19 devnull char tmp[10]; /* just in case */
87 a84cbb2a 2004-04-19 devnull return pc2file(pc, tmp, sizeof tmp, line);
88 a84cbb2a 2004-04-19 devnull }
89 a84cbb2a 2004-04-19 devnull
90 a84cbb2a 2004-04-19 devnull int
91 443d6288 2012-02-19 rsc file2pc(char *file, ulong line, u64int *addr)
92 a84cbb2a 2004-04-19 devnull {
93 a84cbb2a 2004-04-19 devnull Fhdr *p;
94 a84cbb2a 2004-04-19 devnull
95 a84cbb2a 2004-04-19 devnull for(p=fhdrlist; p; p=p->next)
96 a84cbb2a 2004-04-19 devnull if(p->file2pc && p->file2pc(p, file, line, addr) >= 0){
97 a84cbb2a 2004-04-19 devnull *addr += p->base;
98 a84cbb2a 2004-04-19 devnull return 0;
99 a84cbb2a 2004-04-19 devnull }
100 a84cbb2a 2004-04-19 devnull werrstr("no instructions at %s:%lud", file, line);
101 a84cbb2a 2004-04-19 devnull return -1;
102 a84cbb2a 2004-04-19 devnull }
103 a84cbb2a 2004-04-19 devnull
104 a84cbb2a 2004-04-19 devnull int
105 443d6288 2012-02-19 rsc line2pc(u64int basepc, ulong line, u64int *pc)
106 a84cbb2a 2004-04-19 devnull {
107 a84cbb2a 2004-04-19 devnull Fhdr *p;
108 a84cbb2a 2004-04-19 devnull
109 a84cbb2a 2004-04-19 devnull for(p=fhdrlist; p; p=p->next)
110 a84cbb2a 2004-04-19 devnull if(p->line2pc && p->line2pc(p, basepc-p->base, line, pc) >= 0){
111 a84cbb2a 2004-04-19 devnull *pc += p->base;
112 a84cbb2a 2004-04-19 devnull return 0;
113 a84cbb2a 2004-04-19 devnull }
114 a84cbb2a 2004-04-19 devnull werrstr("no instructions on line %lud", line);
115 a84cbb2a 2004-04-19 devnull return -1;
116 a84cbb2a 2004-04-19 devnull }
117 a84cbb2a 2004-04-19 devnull
118 a84cbb2a 2004-04-19 devnull int
119 443d6288 2012-02-19 rsc fnbound(u64int pc, u64int *bounds)
120 a84cbb2a 2004-04-19 devnull {
121 a84cbb2a 2004-04-19 devnull Fhdr *p;
122 a84cbb2a 2004-04-19 devnull Loc l;
123 a84cbb2a 2004-04-19 devnull Symbol *s;
124 a84cbb2a 2004-04-19 devnull
125 a84cbb2a 2004-04-19 devnull for(p=fhdrlist; p; p=p->next){
126 a84cbb2a 2004-04-19 devnull l = locaddr(pc - p->base);
127 a84cbb2a 2004-04-19 devnull if((s = ffindsym(p, l, CANY)) != nil){
128 a84cbb2a 2004-04-19 devnull if(s->loc.type != LADDR){
129 a84cbb2a 2004-04-19 devnull werrstr("function %s has weird location %L", s->name, s->loc);
130 a84cbb2a 2004-04-19 devnull return -1;
131 a84cbb2a 2004-04-19 devnull }
132 a84cbb2a 2004-04-19 devnull bounds[0] = s->loc.addr + p->base;
133 a84cbb2a 2004-04-19 devnull if(s->hiloc.type != LADDR){
134 a84cbb2a 2004-04-19 devnull werrstr("can't find upper bound for function %s", s->name);
135 a84cbb2a 2004-04-19 devnull return -1;
136 a84cbb2a 2004-04-19 devnull }
137 a84cbb2a 2004-04-19 devnull bounds[1] = s->hiloc.addr + p->base;
138 a84cbb2a 2004-04-19 devnull return 0;
139 a84cbb2a 2004-04-19 devnull }
140 a84cbb2a 2004-04-19 devnull }
141 a84cbb2a 2004-04-19 devnull werrstr("no function contains 0x%lux", pc);
142 a84cbb2a 2004-04-19 devnull return -1;
143 a84cbb2a 2004-04-19 devnull }
144 a84cbb2a 2004-04-19 devnull
145 a84cbb2a 2004-04-19 devnull int
146 443d6288 2012-02-19 rsc fileline(u64int pc, char *a, uint n)
147 a84cbb2a 2004-04-19 devnull {
148 a84cbb2a 2004-04-19 devnull ulong line;
149 a84cbb2a 2004-04-19 devnull
150 a84cbb2a 2004-04-19 devnull if(pc2file(pc, a, n, &line) < 0)
151 a84cbb2a 2004-04-19 devnull return -1;
152 a84cbb2a 2004-04-19 devnull seprint(a+strlen(a), a+n, ":%lud", line);
153 a84cbb2a 2004-04-19 devnull return 0;
154 a84cbb2a 2004-04-19 devnull }
155 a84cbb2a 2004-04-19 devnull
156 a84cbb2a 2004-04-19 devnull Symbol*
157 a84cbb2a 2004-04-19 devnull flookupsym(Fhdr *fhdr, char *name)
158 a84cbb2a 2004-04-19 devnull {
159 a84cbb2a 2004-04-19 devnull Symbol **a, *t;
160 a84cbb2a 2004-04-19 devnull uint n, m;
161 a84cbb2a 2004-04-19 devnull int i;
162 a84cbb2a 2004-04-19 devnull
163 a84cbb2a 2004-04-19 devnull a = fhdr->byname;
164 a84cbb2a 2004-04-19 devnull n = fhdr->nsym;
165 a84cbb2a 2004-04-19 devnull if(a == nil)
166 a84cbb2a 2004-04-19 devnull return nil;
167 a84cbb2a 2004-04-19 devnull
168 a84cbb2a 2004-04-19 devnull while(n > 0){
169 a84cbb2a 2004-04-19 devnull m = n/2;
170 a84cbb2a 2004-04-19 devnull t = a[m];
171 a84cbb2a 2004-04-19 devnull i = strcmp(name, t->name);
172 a84cbb2a 2004-04-19 devnull if(i < 0)
173 a84cbb2a 2004-04-19 devnull n = m;
174 a84cbb2a 2004-04-19 devnull else if(i > 0){
175 a84cbb2a 2004-04-19 devnull n -= m+1;
176 a84cbb2a 2004-04-19 devnull a += m+1;
177 a84cbb2a 2004-04-19 devnull }else{
178 a84cbb2a 2004-04-19 devnull /* found! */
179 a84cbb2a 2004-04-19 devnull m += a - fhdr->byname;
180 a84cbb2a 2004-04-19 devnull a = fhdr->byname;
181 a84cbb2a 2004-04-19 devnull assert(strcmp(name, a[m]->name) == 0);
182 a84cbb2a 2004-04-19 devnull while(m > 0 && strcmp(name, a[m-1]->name) == 0)
183 a84cbb2a 2004-04-19 devnull m--;
184 a84cbb2a 2004-04-19 devnull return a[m];
185 a84cbb2a 2004-04-19 devnull }
186 a84cbb2a 2004-04-19 devnull }
187 a84cbb2a 2004-04-19 devnull return nil;
188 a84cbb2a 2004-04-19 devnull }
189 a84cbb2a 2004-04-19 devnull
190 7dc9c4c6 2005-11-29 devnull Symbol*
191 7dc9c4c6 2005-11-29 devnull flookupsymx(Fhdr *fhdr, char *name)
192 7dc9c4c6 2005-11-29 devnull {
193 7dc9c4c6 2005-11-29 devnull Symbol **a, *t;
194 7dc9c4c6 2005-11-29 devnull uint n, m;
195 7dc9c4c6 2005-11-29 devnull int i;
196 7dc9c4c6 2005-11-29 devnull
197 7dc9c4c6 2005-11-29 devnull a = fhdr->byxname;
198 7dc9c4c6 2005-11-29 devnull n = fhdr->nsym;
199 7dc9c4c6 2005-11-29 devnull if(a == nil)
200 7dc9c4c6 2005-11-29 devnull return nil;
201 7dc9c4c6 2005-11-29 devnull
202 7dc9c4c6 2005-11-29 devnull while(n > 0){
203 7dc9c4c6 2005-11-29 devnull m = n/2;
204 7dc9c4c6 2005-11-29 devnull t = a[m];
205 7dc9c4c6 2005-11-29 devnull i = strcmp(name, t->xname);
206 7dc9c4c6 2005-11-29 devnull if(i < 0)
207 7dc9c4c6 2005-11-29 devnull n = m;
208 7dc9c4c6 2005-11-29 devnull else if(i > 0){
209 7dc9c4c6 2005-11-29 devnull n -= m+1;
210 7dc9c4c6 2005-11-29 devnull a += m+1;
211 7dc9c4c6 2005-11-29 devnull }else{
212 7dc9c4c6 2005-11-29 devnull /* found! */
213 7dc9c4c6 2005-11-29 devnull m += a - fhdr->byxname;
214 7dc9c4c6 2005-11-29 devnull a = fhdr->byxname;
215 7dc9c4c6 2005-11-29 devnull assert(strcmp(name, a[m]->xname) == 0);
216 7dc9c4c6 2005-11-29 devnull while(m > 0 && strcmp(name, a[m-1]->xname) == 0)
217 7dc9c4c6 2005-11-29 devnull m--;
218 7dc9c4c6 2005-11-29 devnull return a[m];
219 7dc9c4c6 2005-11-29 devnull }
220 7dc9c4c6 2005-11-29 devnull }
221 7dc9c4c6 2005-11-29 devnull return nil;
222 7dc9c4c6 2005-11-29 devnull }
223 7dc9c4c6 2005-11-29 devnull
224 a84cbb2a 2004-04-19 devnull int
225 a84cbb2a 2004-04-19 devnull lookupsym(char *fn, char *var, Symbol *s)
226 a84cbb2a 2004-04-19 devnull {
227 a84cbb2a 2004-04-19 devnull Symbol *t, s1;
228 a84cbb2a 2004-04-19 devnull Fhdr *p;
229 a84cbb2a 2004-04-19 devnull char *nam;
230 a84cbb2a 2004-04-19 devnull
231 a84cbb2a 2004-04-19 devnull nam = fn ? fn : var;
232 a84cbb2a 2004-04-19 devnull if(nam == nil)
233 a84cbb2a 2004-04-19 devnull return -1;
234 a84cbb2a 2004-04-19 devnull t = nil;
235 a84cbb2a 2004-04-19 devnull for(p=fhdrlist; p; p=p->next)
236 7dc9c4c6 2005-11-29 devnull if((t=flookupsym(p, nam)) != nil
237 7dc9c4c6 2005-11-29 devnull || (t=flookupsymx(p, nam)) != nil){
238 a84cbb2a 2004-04-19 devnull relocsym(&s1, t, p->base);
239 a84cbb2a 2004-04-19 devnull break;
240 a84cbb2a 2004-04-19 devnull }
241 7dc9c4c6 2005-11-29 devnull
242 a84cbb2a 2004-04-19 devnull if(t == nil)
243 a84cbb2a 2004-04-19 devnull goto err;
244 a84cbb2a 2004-04-19 devnull if(fn && var)
245 a84cbb2a 2004-04-19 devnull return lookuplsym(&s1, var, s);
246 a84cbb2a 2004-04-19 devnull *s = s1;
247 a84cbb2a 2004-04-19 devnull return 0;
248 a84cbb2a 2004-04-19 devnull
249 a84cbb2a 2004-04-19 devnull err:
250 a84cbb2a 2004-04-19 devnull werrstr("unknown symbol %s%s%s", fn ? fn : "",
251 a84cbb2a 2004-04-19 devnull fn && var ? ":" : "", var ? var : "");
252 a84cbb2a 2004-04-19 devnull return -1;
253 a84cbb2a 2004-04-19 devnull }
254 a84cbb2a 2004-04-19 devnull
255 a84cbb2a 2004-04-19 devnull int
256 a84cbb2a 2004-04-19 devnull findexsym(Fhdr *fp, uint i, Symbol *s)
257 a84cbb2a 2004-04-19 devnull {
258 a84cbb2a 2004-04-19 devnull if(i >= fp->nsym)
259 a84cbb2a 2004-04-19 devnull return -1;
260 a84cbb2a 2004-04-19 devnull relocsym(s, &fp->sym[i], fp->base);
261 a84cbb2a 2004-04-19 devnull return 0;
262 a84cbb2a 2004-04-19 devnull }
263 a84cbb2a 2004-04-19 devnull
264 a84cbb2a 2004-04-19 devnull int
265 a84cbb2a 2004-04-19 devnull indexsym(uint ndx, Symbol *s)
266 a84cbb2a 2004-04-19 devnull {
267 a84cbb2a 2004-04-19 devnull uint t;
268 a84cbb2a 2004-04-19 devnull Fhdr *p;
269 a84cbb2a 2004-04-19 devnull
270 a84cbb2a 2004-04-19 devnull for(p=fhdrlist; p; p=p->next){
271 a84cbb2a 2004-04-19 devnull t = p->nsym;
272 a84cbb2a 2004-04-19 devnull if(t < ndx)
273 a84cbb2a 2004-04-19 devnull ndx -= t;
274 a84cbb2a 2004-04-19 devnull else{
275 a84cbb2a 2004-04-19 devnull relocsym(s, &p->sym[ndx], p->base);
276 a84cbb2a 2004-04-19 devnull return 0;
277 a84cbb2a 2004-04-19 devnull }
278 a84cbb2a 2004-04-19 devnull }
279 a84cbb2a 2004-04-19 devnull return -1;
280 a84cbb2a 2004-04-19 devnull }
281 a84cbb2a 2004-04-19 devnull
282 a84cbb2a 2004-04-19 devnull Symbol*
283 a84cbb2a 2004-04-19 devnull ffindsym(Fhdr *fhdr, Loc loc, uint class)
284 a84cbb2a 2004-04-19 devnull {
285 a84cbb2a 2004-04-19 devnull Symbol *a, *t;
286 a84cbb2a 2004-04-19 devnull int n, i, hi, lo;
287 a84cbb2a 2004-04-19 devnull int cmp;
288 a84cbb2a 2004-04-19 devnull
289 a84cbb2a 2004-04-19 devnull a = fhdr->sym;
290 a84cbb2a 2004-04-19 devnull n = fhdr->nsym;
291 a84cbb2a 2004-04-19 devnull if(a == nil || n <= 0)
292 a84cbb2a 2004-04-19 devnull return nil;
293 a84cbb2a 2004-04-19 devnull
294 a84cbb2a 2004-04-19 devnull /*
295 a84cbb2a 2004-04-19 devnull * We have a list of possibly duplicate locations in a.
296 a84cbb2a 2004-04-19 devnull * We want to find the largest index i such that
297 a84cbb2a 2004-04-19 devnull * a[i] <= loc. This cannot be done with a simple
298 a84cbb2a 2004-04-19 devnull * binary search. Instead we binary search to find
299 fa325e9b 2020-01-10 cross * where the location should be.
300 a84cbb2a 2004-04-19 devnull */
301 a84cbb2a 2004-04-19 devnull lo = 0;
302 a84cbb2a 2004-04-19 devnull hi = n;
303 a84cbb2a 2004-04-19 devnull while(lo < hi){
304 a84cbb2a 2004-04-19 devnull i = (lo+hi)/2;
305 a84cbb2a 2004-04-19 devnull cmp = loccmp(&loc, &a[i].loc);
306 a84cbb2a 2004-04-19 devnull if(cmp < 0) /* loc < a[i].loc */
307 a84cbb2a 2004-04-19 devnull hi = i;
308 a84cbb2a 2004-04-19 devnull if(cmp > 0) /* loc > a[i].loc */
309 a84cbb2a 2004-04-19 devnull lo = i+1;
310 a84cbb2a 2004-04-19 devnull if(cmp == 0)
311 a84cbb2a 2004-04-19 devnull goto found;
312 a84cbb2a 2004-04-19 devnull }
313 a84cbb2a 2004-04-19 devnull
314 a84cbb2a 2004-04-19 devnull /* found position where value would go, but not there -- go back one */
315 a84cbb2a 2004-04-19 devnull if(lo == 0)
316 a84cbb2a 2004-04-19 devnull return nil;
317 a84cbb2a 2004-04-19 devnull i = lo-1;
318 a84cbb2a 2004-04-19 devnull
319 a84cbb2a 2004-04-19 devnull found:
320 a84cbb2a 2004-04-19 devnull /*
321 a84cbb2a 2004-04-19 devnull * might be in a run of all-the-same -- go back to beginning of run.
322 a84cbb2a 2004-04-19 devnull * if runs were long, could binary search for a[i].loc instead.
323 a84cbb2a 2004-04-19 devnull */
324 a84cbb2a 2004-04-19 devnull while(i > 0 && loccmp(&a[i-1].loc, &a[i].loc) == 0)
325 a84cbb2a 2004-04-19 devnull i--;
326 a84cbb2a 2004-04-19 devnull
327 a84cbb2a 2004-04-19 devnull t = &a[i];
328 a84cbb2a 2004-04-19 devnull if(t->hiloc.type && loccmp(&loc, &t->hiloc) >= 0)
329 a84cbb2a 2004-04-19 devnull return nil;
330 a84cbb2a 2004-04-19 devnull if(class != CANY && class != t->class)
331 a84cbb2a 2004-04-19 devnull return nil;
332 a84cbb2a 2004-04-19 devnull return t;
333 a84cbb2a 2004-04-19 devnull }
334 a84cbb2a 2004-04-19 devnull
335 a84cbb2a 2004-04-19 devnull int
336 a84cbb2a 2004-04-19 devnull findsym(Loc loc, uint class, Symbol *s)
337 a84cbb2a 2004-04-19 devnull {
338 a84cbb2a 2004-04-19 devnull Fhdr *p, *bestp;
339 a84cbb2a 2004-04-19 devnull Symbol *t, *best;
340 a84cbb2a 2004-04-19 devnull long bestd, d;
341 a84cbb2a 2004-04-19 devnull Loc l;
342 a84cbb2a 2004-04-19 devnull
343 a84cbb2a 2004-04-19 devnull l = loc;
344 a84cbb2a 2004-04-19 devnull best = nil;
345 a84cbb2a 2004-04-19 devnull bestp = nil;
346 a84cbb2a 2004-04-19 devnull bestd = 0;
347 a84cbb2a 2004-04-19 devnull for(p=fhdrlist; p; p=p->next){
348 a84cbb2a 2004-04-19 devnull if(l.type == LADDR)
349 a84cbb2a 2004-04-19 devnull l.addr = loc.addr - p->base;
350 a84cbb2a 2004-04-19 devnull if((t = ffindsym(p, l, CANY)) != nil){
351 a84cbb2a 2004-04-19 devnull d = l.addr - t->loc.addr;
352 62c277ef 2004-04-20 devnull if(0 <= d && d < 4096)
353 a84cbb2a 2004-04-19 devnull if(best == nil || d < bestd){
354 a84cbb2a 2004-04-19 devnull best = t;
355 a84cbb2a 2004-04-19 devnull bestp = p;
356 a84cbb2a 2004-04-19 devnull bestd = d;
357 a84cbb2a 2004-04-19 devnull }
358 a84cbb2a 2004-04-19 devnull }
359 a84cbb2a 2004-04-19 devnull }
360 a84cbb2a 2004-04-19 devnull if(best){
361 a84cbb2a 2004-04-19 devnull if(class != CANY && class != best->class)
362 a84cbb2a 2004-04-19 devnull goto err;
363 a84cbb2a 2004-04-19 devnull relocsym(s, best, bestp->base);
364 a84cbb2a 2004-04-19 devnull return 0;
365 a84cbb2a 2004-04-19 devnull }
366 a84cbb2a 2004-04-19 devnull err:
367 a84cbb2a 2004-04-19 devnull werrstr("could not find symbol at %L", loc);
368 a84cbb2a 2004-04-19 devnull return -1;
369 a84cbb2a 2004-04-19 devnull }
370 a84cbb2a 2004-04-19 devnull
371 a84cbb2a 2004-04-19 devnull int
372 a84cbb2a 2004-04-19 devnull lookuplsym(Symbol *s1, char *name, Symbol *s2)
373 a84cbb2a 2004-04-19 devnull {
374 a84cbb2a 2004-04-19 devnull Fhdr *p;
375 a84cbb2a 2004-04-19 devnull
376 a84cbb2a 2004-04-19 devnull p = s1->fhdr;
377 a84cbb2a 2004-04-19 devnull if(p->lookuplsym && p->lookuplsym(p, s1, name, s2) >= 0){
378 a84cbb2a 2004-04-19 devnull relocsym(s2, s2, p->base);
379 a84cbb2a 2004-04-19 devnull return 0;
380 a84cbb2a 2004-04-19 devnull }
381 a84cbb2a 2004-04-19 devnull return -1;
382 a84cbb2a 2004-04-19 devnull }
383 a84cbb2a 2004-04-19 devnull
384 a84cbb2a 2004-04-19 devnull int
385 a84cbb2a 2004-04-19 devnull indexlsym(Symbol *s1, uint ndx, Symbol *s2)
386 a84cbb2a 2004-04-19 devnull {
387 a84cbb2a 2004-04-19 devnull Fhdr *p;
388 a84cbb2a 2004-04-19 devnull
389 a84cbb2a 2004-04-19 devnull p = s1->fhdr;
390 a84cbb2a 2004-04-19 devnull if(p->indexlsym && p->indexlsym(p, s1, ndx, s2) >= 0){
391 a84cbb2a 2004-04-19 devnull relocsym(s2, s2, p->base);
392 a84cbb2a 2004-04-19 devnull return 0;
393 a84cbb2a 2004-04-19 devnull }
394 a84cbb2a 2004-04-19 devnull return -1;
395 a84cbb2a 2004-04-19 devnull }
396 a84cbb2a 2004-04-19 devnull
397 a84cbb2a 2004-04-19 devnull int
398 a84cbb2a 2004-04-19 devnull findlsym(Symbol *s1, Loc loc, Symbol *s2)
399 a84cbb2a 2004-04-19 devnull {
400 a84cbb2a 2004-04-19 devnull Fhdr *p;
401 a84cbb2a 2004-04-19 devnull
402 a84cbb2a 2004-04-19 devnull p = s1->fhdr;
403 a84cbb2a 2004-04-19 devnull if(p->findlsym && p->findlsym(p, s1, loc, s2) >= 0){
404 a84cbb2a 2004-04-19 devnull relocsym(s2, s2, p->base);
405 a84cbb2a 2004-04-19 devnull return 0;
406 a84cbb2a 2004-04-19 devnull }
407 a84cbb2a 2004-04-19 devnull return -1;
408 a84cbb2a 2004-04-19 devnull }
409 a84cbb2a 2004-04-19 devnull
410 a84cbb2a 2004-04-19 devnull int
411 443d6288 2012-02-19 rsc unwindframe(Map *map, Regs *regs, u64int *next, Symbol *sym)
412 a84cbb2a 2004-04-19 devnull {
413 a84cbb2a 2004-04-19 devnull Fhdr *p;
414 a84cbb2a 2004-04-19 devnull
415 a84cbb2a 2004-04-19 devnull for(p=fhdrlist; p; p=p->next)
416 1cc215aa 2004-12-25 devnull if(p->unwind && p->unwind(p, map, regs, next, sym) >= 0)
417 a84cbb2a 2004-04-19 devnull return 0;
418 1cc215aa 2004-12-25 devnull if(mach->unwind && mach->unwind(map, regs, next, sym) >= 0)
419 a84cbb2a 2004-04-19 devnull return 0;
420 a84cbb2a 2004-04-19 devnull return -1;
421 a84cbb2a 2004-04-19 devnull }
422 a84cbb2a 2004-04-19 devnull
423 a84cbb2a 2004-04-19 devnull int
424 443d6288 2012-02-19 rsc symoff(char *a, uint n, u64int addr, uint class)
425 a84cbb2a 2004-04-19 devnull {
426 a84cbb2a 2004-04-19 devnull Loc l;
427 a84cbb2a 2004-04-19 devnull Symbol s;
428 a84cbb2a 2004-04-19 devnull
429 a84cbb2a 2004-04-19 devnull l.type = LADDR;
430 a84cbb2a 2004-04-19 devnull l.addr = addr;
431 a84cbb2a 2004-04-19 devnull if(findsym(l, class, &s) < 0 || addr-s.loc.addr >= 4096){
432 fbca1e1c 2005-02-11 devnull snprint(a, n, "%#lux", addr);
433 a84cbb2a 2004-04-19 devnull return -1;
434 a84cbb2a 2004-04-19 devnull }
435 a84cbb2a 2004-04-19 devnull if(addr != s.loc.addr)
436 fbca1e1c 2005-02-11 devnull snprint(a, n, "%s+%#lx", s.name, addr-s.loc.addr);
437 a84cbb2a 2004-04-19 devnull else
438 a84cbb2a 2004-04-19 devnull snprint(a, n, "%s", s.name);
439 a84cbb2a 2004-04-19 devnull return 0;
440 a84cbb2a 2004-04-19 devnull }
441 a84cbb2a 2004-04-19 devnull
442 a84cbb2a 2004-04-19 devnull /* location, class, name */
443 a84cbb2a 2004-04-19 devnull static int
444 a84cbb2a 2004-04-19 devnull byloccmp(const void *va, const void *vb)
445 a84cbb2a 2004-04-19 devnull {
446 a84cbb2a 2004-04-19 devnull int i;
447 a84cbb2a 2004-04-19 devnull Symbol *a, *b;
448 a84cbb2a 2004-04-19 devnull
449 a84cbb2a 2004-04-19 devnull a = (Symbol*)va;
450 a84cbb2a 2004-04-19 devnull b = (Symbol*)vb;
451 a84cbb2a 2004-04-19 devnull i = loccmp(&a->loc, &b->loc);
452 a84cbb2a 2004-04-19 devnull if(i != 0)
453 a84cbb2a 2004-04-19 devnull return i;
454 a84cbb2a 2004-04-19 devnull i = a->class - b->class;
455 a84cbb2a 2004-04-19 devnull if(i != 0)
456 a84cbb2a 2004-04-19 devnull return i;
457 a84cbb2a 2004-04-19 devnull return strcmp(a->name, b->name);
458 a84cbb2a 2004-04-19 devnull }
459 a84cbb2a 2004-04-19 devnull
460 a84cbb2a 2004-04-19 devnull /* name, location, class */
461 a84cbb2a 2004-04-19 devnull static int
462 7dc9c4c6 2005-11-29 devnull byxnamecmp(const void *va, const void *vb)
463 7dc9c4c6 2005-11-29 devnull {
464 7dc9c4c6 2005-11-29 devnull int i;
465 7dc9c4c6 2005-11-29 devnull Symbol *a, *b;
466 7dc9c4c6 2005-11-29 devnull
467 7dc9c4c6 2005-11-29 devnull a = *(Symbol**)va;
468 7dc9c4c6 2005-11-29 devnull b = *(Symbol**)vb;
469 7dc9c4c6 2005-11-29 devnull i = strcmp(a->xname, b->xname);
470 7dc9c4c6 2005-11-29 devnull if(i != 0)
471 7dc9c4c6 2005-11-29 devnull return i;
472 7dc9c4c6 2005-11-29 devnull i = strcmp(a->name, b->name);
473 7dc9c4c6 2005-11-29 devnull if(i != 0)
474 7dc9c4c6 2005-11-29 devnull return i;
475 7dc9c4c6 2005-11-29 devnull i = loccmp(&a->loc, &b->loc);
476 7dc9c4c6 2005-11-29 devnull if(i != 0)
477 7dc9c4c6 2005-11-29 devnull return i;
478 7dc9c4c6 2005-11-29 devnull return a->class - b->class;
479 7dc9c4c6 2005-11-29 devnull }
480 7dc9c4c6 2005-11-29 devnull
481 7dc9c4c6 2005-11-29 devnull /* name, location, class */
482 7dc9c4c6 2005-11-29 devnull static int
483 a84cbb2a 2004-04-19 devnull bynamecmp(const void *va, const void *vb)
484 a84cbb2a 2004-04-19 devnull {
485 a84cbb2a 2004-04-19 devnull int i;
486 a84cbb2a 2004-04-19 devnull Symbol *a, *b;
487 a84cbb2a 2004-04-19 devnull
488 a84cbb2a 2004-04-19 devnull a = *(Symbol**)va;
489 a84cbb2a 2004-04-19 devnull b = *(Symbol**)vb;
490 a84cbb2a 2004-04-19 devnull i = strcmp(a->name, b->name);
491 a84cbb2a 2004-04-19 devnull if(i != 0)
492 a84cbb2a 2004-04-19 devnull return i;
493 a84cbb2a 2004-04-19 devnull i = loccmp(&a->loc, &b->loc);
494 a84cbb2a 2004-04-19 devnull if(i != 0)
495 a84cbb2a 2004-04-19 devnull return i;
496 a84cbb2a 2004-04-19 devnull return a->class - b->class;
497 a84cbb2a 2004-04-19 devnull }
498 a84cbb2a 2004-04-19 devnull
499 a84cbb2a 2004-04-19 devnull int
500 39dbe6e7 2005-01-07 devnull symopen(Fhdr *hdr)
501 a84cbb2a 2004-04-19 devnull {
502 a84cbb2a 2004-04-19 devnull int i;
503 a84cbb2a 2004-04-19 devnull Symbol *r, *w, *es;
504 a84cbb2a 2004-04-19 devnull
505 a8763864 2004-07-09 devnull if(hdr->syminit == 0){
506 a84cbb2a 2004-04-19 devnull werrstr("no debugging symbols");
507 a84cbb2a 2004-04-19 devnull return -1;
508 a84cbb2a 2004-04-19 devnull }
509 a84cbb2a 2004-04-19 devnull if(hdr->syminit(hdr) < 0)
510 a84cbb2a 2004-04-19 devnull return -1;
511 a84cbb2a 2004-04-19 devnull
512 a84cbb2a 2004-04-19 devnull qsort(hdr->sym, hdr->nsym, sizeof(hdr->sym[0]), byloccmp);
513 a84cbb2a 2004-04-19 devnull es = hdr->sym+hdr->nsym;
514 a84cbb2a 2004-04-19 devnull for(r=w=hdr->sym; r<es; r++){
515 a84cbb2a 2004-04-19 devnull if(w > hdr->sym
516 a84cbb2a 2004-04-19 devnull && strcmp((w-1)->name, r->name) ==0
517 a84cbb2a 2004-04-19 devnull && loccmp(&(w-1)->loc, &r->loc) == 0){
518 a84cbb2a 2004-04-19 devnull /* skip it */
519 a84cbb2a 2004-04-19 devnull }else
520 a84cbb2a 2004-04-19 devnull *w++ = *r;
521 a84cbb2a 2004-04-19 devnull }
522 a84cbb2a 2004-04-19 devnull hdr->nsym = w - hdr->sym;
523 a84cbb2a 2004-04-19 devnull
524 a84cbb2a 2004-04-19 devnull hdr->byname = malloc(hdr->nsym*sizeof(hdr->byname[0]));
525 a84cbb2a 2004-04-19 devnull if(hdr->byname == nil){
526 7dc9c4c6 2005-11-29 devnull fprint(2, "could not allocate table to sort by name\n");
527 a84cbb2a 2004-04-19 devnull }else{
528 a84cbb2a 2004-04-19 devnull for(i=0; i<hdr->nsym; i++)
529 a84cbb2a 2004-04-19 devnull hdr->byname[i] = &hdr->sym[i];
530 a84cbb2a 2004-04-19 devnull qsort(hdr->byname, hdr->nsym, sizeof(hdr->byname[0]), bynamecmp);
531 a84cbb2a 2004-04-19 devnull }
532 fa325e9b 2020-01-10 cross
533 7dc9c4c6 2005-11-29 devnull hdr->byxname = malloc(hdr->nsym*sizeof(hdr->byxname[0]));
534 7dc9c4c6 2005-11-29 devnull if(hdr->byxname == nil){
535 7dc9c4c6 2005-11-29 devnull fprint(2, "could not allocate table to sort by xname\n");
536 7dc9c4c6 2005-11-29 devnull }else{
537 7dc9c4c6 2005-11-29 devnull for(i=0; i<hdr->nsym; i++)
538 7dc9c4c6 2005-11-29 devnull hdr->byxname[i] = &hdr->sym[i];
539 7dc9c4c6 2005-11-29 devnull qsort(hdr->byxname, hdr->nsym, sizeof(hdr->byxname[0]), byxnamecmp);
540 7dc9c4c6 2005-11-29 devnull }
541 a84cbb2a 2004-04-19 devnull return 0;
542 a84cbb2a 2004-04-19 devnull }
543 a84cbb2a 2004-04-19 devnull
544 39dbe6e7 2005-01-07 devnull void
545 39dbe6e7 2005-01-07 devnull symclose(Fhdr *hdr)
546 39dbe6e7 2005-01-07 devnull {
547 39dbe6e7 2005-01-07 devnull _delhdr(hdr);
548 39dbe6e7 2005-01-07 devnull if(hdr->symclose)
549 39dbe6e7 2005-01-07 devnull hdr->symclose(hdr);
550 39dbe6e7 2005-01-07 devnull free(hdr->byname);
551 39dbe6e7 2005-01-07 devnull hdr->byname = nil;
552 39dbe6e7 2005-01-07 devnull free(hdr->sym);
553 39dbe6e7 2005-01-07 devnull hdr->sym = nil;
554 39dbe6e7 2005-01-07 devnull hdr->nsym = 0;
555 39dbe6e7 2005-01-07 devnull }
556 39dbe6e7 2005-01-07 devnull
557 a84cbb2a 2004-04-19 devnull Symbol*
558 39dbe6e7 2005-01-07 devnull _addsym(Fhdr *fp, Symbol *sym)
559 a84cbb2a 2004-04-19 devnull {
560 7d6f5677 2005-11-28 devnull char *t;
561 7d6f5677 2005-11-28 devnull static char buf[65536];
562 a84cbb2a 2004-04-19 devnull Symbol *s;
563 a84cbb2a 2004-04-19 devnull
564 a84cbb2a 2004-04-19 devnull if(fp->nsym%128 == 0){
565 a84cbb2a 2004-04-19 devnull s = realloc(fp->sym, (fp->nsym+128)*sizeof(fp->sym[0]));
566 a84cbb2a 2004-04-19 devnull if(s == nil)
567 a84cbb2a 2004-04-19 devnull return nil;
568 a84cbb2a 2004-04-19 devnull fp->sym = s;
569 a84cbb2a 2004-04-19 devnull }
570 a84cbb2a 2004-04-19 devnull if(machdebug)
571 a84cbb2a 2004-04-19 devnull fprint(2, "sym %s %c %L\n", sym->name, sym->type, sym->loc);
572 a84cbb2a 2004-04-19 devnull sym->fhdr = fp;
573 7d6f5677 2005-11-28 devnull t = demangle(sym->name, buf, 1);
574 7d6f5677 2005-11-28 devnull if(t != sym->name){
575 7dc9c4c6 2005-11-29 devnull t = strdup(t);
576 7dc9c4c6 2005-11-29 devnull if(t == nil)
577 7d6f5677 2005-11-28 devnull return nil;
578 7d6f5677 2005-11-28 devnull }
579 7dc9c4c6 2005-11-29 devnull sym->xname = t;
580 a84cbb2a 2004-04-19 devnull s = &fp->sym[fp->nsym++];
581 a84cbb2a 2004-04-19 devnull *s = *sym;
582 a84cbb2a 2004-04-19 devnull return s;
583 a84cbb2a 2004-04-19 devnull }