12 relocsym(Symbol *dst, Symbol *src, ulong base)
16 if(dst->loc.type == LADDR)
17 dst->loc.addr += base;
18 if(dst->hiloc.type == LADDR)
19 dst->hiloc.addr += base;
43 for(p=fhdrlist; p && p->next!=h; p=p->next)
60 for(p=fhdrlist; p; p=p->next){
61 plen = strlen(p->filename);
63 if(strcmp(p->filename+plen-len, name) == 0)
64 if(plen == len || p->filename[plen-len-1] == '/')
71 pc2file(ulong pc, char *file, uint nfile, ulong *line)
75 for(p=fhdrlist; p; p=p->next)
76 if(p->pc2file && p->pc2file(p, pc-p->base, file, nfile, line) >= 0)
78 werrstr("no source file for 0x%lux", pc);
83 pc2line(ulong pc, ulong *line)
85 char tmp[10]; /* just in case */
86 return pc2file(pc, tmp, sizeof tmp, line);
90 file2pc(char *file, ulong line, ulong *addr)
94 for(p=fhdrlist; p; p=p->next)
95 if(p->file2pc && p->file2pc(p, file, line, addr) >= 0){
99 werrstr("no instructions at %s:%lud", file, line);
104 line2pc(ulong basepc, ulong line, ulong *pc)
108 for(p=fhdrlist; p; p=p->next)
109 if(p->line2pc && p->line2pc(p, basepc-p->base, line, pc) >= 0){
113 werrstr("no instructions on line %lud", line);
118 fnbound(ulong pc, ulong *bounds)
124 for(p=fhdrlist; p; p=p->next){
125 l = locaddr(pc - p->base);
126 if((s = ffindsym(p, l, CANY)) != nil){
127 if(s->loc.type != LADDR){
128 werrstr("function %s has weird location %L", s->name, s->loc);
131 bounds[0] = s->loc.addr + p->base;
132 if(s->hiloc.type != LADDR){
133 werrstr("can't find upper bound for function %s", s->name);
136 bounds[1] = s->hiloc.addr + p->base;
140 werrstr("no function contains 0x%lux", pc);
145 fileline(ulong pc, char *a, uint n)
149 if(pc2file(pc, a, n, &line) < 0)
151 seprint(a+strlen(a), a+n, ":%lud", line);
156 flookupsym(Fhdr *fhdr, char *name)
170 i = strcmp(name, t->name);
178 m += a - fhdr->byname;
180 assert(strcmp(name, a[m]->name) == 0);
181 while(m > 0 && strcmp(name, a[m-1]->name) == 0)
190 lookupsym(char *fn, char *var, Symbol *s)
200 for(p=fhdrlist; p; p=p->next)
201 if((t=flookupsym(p, nam)) != nil){
202 relocsym(&s1, t, p->base);
208 return lookuplsym(&s1, var, s);
213 werrstr("unknown symbol %s%s%s", fn ? fn : "",
214 fn && var ? ":" : "", var ? var : "");
219 findexsym(Fhdr *fp, uint i, Symbol *s)
223 relocsym(s, &fp->sym[i], fp->base);
228 indexsym(uint ndx, Symbol *s)
233 for(p=fhdrlist; p; p=p->next){
238 relocsym(s, &p->sym[ndx], p->base);
246 ffindsym(Fhdr *fhdr, Loc loc, uint class)
254 if(a == nil || n <= 0)
258 * We have a list of possibly duplicate locations in a.
259 * We want to find the largest index i such that
260 * a[i] <= loc. This cannot be done with a simple
261 * binary search. Instead we binary search to find
262 * where the location should be.
268 cmp = loccmp(&loc, &a[i].loc);
269 if(cmp < 0) /* loc < a[i].loc */
271 if(cmp > 0) /* loc > a[i].loc */
277 /* found position where value would go, but not there -- go back one */
284 * might be in a run of all-the-same -- go back to beginning of run.
285 * if runs were long, could binary search for a[i].loc instead.
287 while(i > 0 && loccmp(&a[i-1].loc, &a[i].loc) == 0)
291 if(t->hiloc.type && loccmp(&loc, &t->hiloc) >= 0)
293 if(class != CANY && class != t->class)
299 findsym(Loc loc, uint class, Symbol *s)
310 for(p=fhdrlist; p; p=p->next){
312 l.addr = loc.addr - p->base;
313 if((t = ffindsym(p, l, CANY)) != nil){
314 d = l.addr - t->loc.addr;
315 if(0 <= d && d < 4096)
316 if(best == nil || d < bestd){
324 if(class != CANY && class != best->class)
326 relocsym(s, best, bestp->base);
330 werrstr("could not find symbol at %L", loc);
335 lookuplsym(Symbol *s1, char *name, Symbol *s2)
340 if(p->lookuplsym && p->lookuplsym(p, s1, name, s2) >= 0){
341 relocsym(s2, s2, p->base);
348 indexlsym(Symbol *s1, uint ndx, Symbol *s2)
353 if(p->indexlsym && p->indexlsym(p, s1, ndx, s2) >= 0){
354 relocsym(s2, s2, p->base);
361 findlsym(Symbol *s1, Loc loc, Symbol *s2)
366 if(p->findlsym && p->findlsym(p, s1, loc, s2) >= 0){
367 relocsym(s2, s2, p->base);
374 unwindframe(Map *map, Regs *regs, ulong *next, Symbol *sym)
378 for(p=fhdrlist; p; p=p->next)
379 if(p->unwind && p->unwind(p, map, regs, next, sym) >= 0)
381 if(mach->unwind && mach->unwind(map, regs, next, sym) >= 0)
387 symoff(char *a, uint n, ulong addr, uint class)
394 if(findsym(l, class, &s) < 0 || addr-s.loc.addr >= 4096){
395 snprint(a, n, "%lux", addr);
398 if(addr != s.loc.addr)
399 snprint(a, n, "%s+%ld", s.name, addr-s.loc.addr);
401 snprint(a, n, "%s", s.name);
405 /* location, class, name */
407 byloccmp(const void *va, const void *vb)
414 i = loccmp(&a->loc, &b->loc);
417 i = a->class - b->class;
420 return strcmp(a->name, b->name);
423 /* name, location, class */
425 bynamecmp(const void *va, const void *vb)
432 i = strcmp(a->name, b->name);
435 i = loccmp(&a->loc, &b->loc);
438 return a->class - b->class;
447 if(hdr->syminit == 0){
448 werrstr("no debugging symbols");
451 if(hdr->syminit(hdr) < 0)
454 qsort(hdr->sym, hdr->nsym, sizeof(hdr->sym[0]), byloccmp);
455 es = hdr->sym+hdr->nsym;
456 for(r=w=hdr->sym; r<es; r++){
458 && strcmp((w-1)->name, r->name) ==0
459 && loccmp(&(w-1)->loc, &r->loc) == 0){
464 hdr->nsym = w - hdr->sym;
466 hdr->byname = malloc(hdr->nsym*sizeof(hdr->byname[0]));
467 if(hdr->byname == nil){
468 fprint(2, "could not allocate table to sort by location\n");
470 for(i=0; i<hdr->nsym; i++)
471 hdr->byname[i] = &hdr->sym[i];
472 qsort(hdr->byname, hdr->nsym, sizeof(hdr->byname[0]), bynamecmp);
478 addsym(Fhdr *fp, Symbol *sym)
482 if(fp->nsym%128 == 0){
483 s = realloc(fp->sym, (fp->nsym+128)*sizeof(fp->sym[0]));
489 fprint(2, "sym %s %c %L\n", sym->name, sym->type, sym->loc);
491 s = &fp->sym[fp->nsym++];