| #include <u.h> |
| #include <libc.h> |
| #include <bio.h> |
| #include "elf.h" |
| #include "dwarf.h" |
| |
| static int |
| _dwarfnametounit(Dwarf *d, char *name, DwarfBlock *bl, DwarfSym *s) |
| { |
| int vers; |
| ulong len, unit, off; |
| uchar *next; |
| char *str; |
| DwarfBuf b; |
| |
| b.d = d; |
| b.p = bl->data; |
| b.ep = b.p + bl->len; |
| |
| while(b.p < b.ep){ |
| len = dwarfget4(&b); |
| if(len > b.ep-b.p){ |
| werrstr("bad length in dwarf name header"); |
| return -1; |
| } |
| next = b.p + len; |
| vers = dwarfget2(&b); |
| if(vers != 1 && vers != 2){ |
| werrstr("bad version %d in dwarf name header", vers); |
| return -1; |
| } |
| unit = dwarfget4(&b); |
| dwarfget4(&b); /* unit length */ |
| while(b.p < next){ |
| off = dwarfget4(&b); |
| if(off == 0) |
| break; |
| str = dwarfgetstring(&b); |
| if(strcmp(str, name) == 0){ |
| if(dwarfenumunit(d, unit, s) < 0) |
| return -1; |
| if(unit + off >= s->b.ep - d->info.data){ |
| werrstr("bad offset in name entry"); |
| return -1; |
| } |
| s->b.p = d->info.data + unit + off; |
| if(dwarfnextsym(d, s) < 0) |
| return -1; |
| if(s->attrs.name==nil || strcmp(s->attrs.name, name)!=0){ |
| werrstr("unexpected name %#q in lookup for %#q", s->attrs.name, name); |
| return -1; |
| } |
| return 0; |
| } |
| } |
| b.p = next; |
| } |
| werrstr("unknown name '%s'", name); |
| return -1; |
| } |
| |
| int |
| dwarflookupname(Dwarf *d, char *name, DwarfSym *sym) |
| { |
| return _dwarfnametounit(d, name, &d->pubnames, sym); |
| } |
| |
| /* |
| |
| int |
| dwarflookuptype(Dwarf *d, char *name, DwarfSym *sym) |
| { |
| return _dwarfnametounit(d, name, &d->pubtypes, sym); |
| } |
| |
| */ |