blob: 728944f42a94e33c9f364817c1c28393ea87046e [file] [log] [blame]
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "elf.h"
#include "dwarf.h"
static int
readblock(int fd, DwarfBlock *b, ulong off, ulong len)
{
b->data = malloc(len);
if(b->data == nil)
return -1;
if(seek(fd, off, 0) < 0 || readn(fd, b->data, len) != len){
free(b->data);
b->data = nil;
return -1;
}
b->len = len;
return 0;
}
static int
findsection(Elf *elf, char *name, ulong *off, ulong *len)
{
ElfSect *s;
if((s = elfsection(elf, name)) == nil)
return -1;
*off = s->offset;
*len = s->size;
return s - elf->sect;
}
static int
loadsection(Elf *elf, char *name, DwarfBlock *b)
{
ulong off, len;
if(findsection(elf, name, &off, &len) < 0)
return -1;
return readblock(elf->fd, b, off, len);
}
Dwarf*
dwarfopen(Elf *elf)
{
Dwarf *d;
if(elf == nil){
werrstr("nil elf passed to dwarfopen");
return nil;
}
d = mallocz(sizeof(Dwarf), 1);
if(d == nil)
return nil;
d->elf = elf;
if(loadsection(elf, ".debug_abbrev", &d->abbrev) < 0
|| loadsection(elf, ".debug_aranges", &d->aranges) < 0
|| loadsection(elf, ".debug_line", &d->line) < 0
|| loadsection(elf, ".debug_pubnames", &d->pubnames) < 0
|| loadsection(elf, ".debug_info", &d->info) < 0)
goto err;
loadsection(elf, ".debug_frame", &d->frame);
loadsection(elf, ".debug_ranges", &d->ranges);
loadsection(elf, ".debug_str", &d->str);
/* make this a table once there are more */
switch(d->elf->hdr.machine){
case ElfMach386:
d->reg = dwarf386regs;
d->nreg = dwarf386nregs;
break;
default:
werrstr("unsupported machine");
goto err;
}
return d;
err:
free(d->abbrev.data);
free(d->aranges.data);
free(d->frame.data);
free(d->line.data);
free(d->pubnames.data);
free(d->ranges.data);
free(d->str.data);
free(d->info.data);
free(d);
return nil;
}
void
dwarfclose(Dwarf *d)
{
free(d->abbrev.data);
free(d->aranges.data);
free(d->frame.data);
free(d->line.data);
free(d->pubnames.data);
free(d->ranges.data);
free(d->str.data);
free(d->info.data);
free(d);
}