#include #include #include #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); }