blob: 68ff911605745af41b119a5e45d5422ab422b430 [file] [log] [blame]
#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);
}
*/