diff options
author | rsc <devnull@localhost> | 2004-04-19 19:29:25 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2004-04-19 19:29:25 +0000 |
commit | a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46 (patch) | |
tree | 59a0e921597e5aa53e83d487c16727a7bf01547a /src/libmach/dwarfopen.c | |
parent | 0e3cc9f456ea49919459bf1164d0c8309a6134fa (diff) | |
download | plan9port-a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46.tar.gz plan9port-a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46.tar.bz2 plan9port-a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46.zip |
libmach
Diffstat (limited to 'src/libmach/dwarfopen.c')
-rw-r--r-- | src/libmach/dwarfopen.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/libmach/dwarfopen.c b/src/libmach/dwarfopen.c new file mode 100644 index 00000000..6122ae68 --- /dev/null +++ b/src/libmach/dwarfopen.c @@ -0,0 +1,107 @@ +#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_frame", &d->frame) < 0 + || loadsection(elf, ".debug_line", &d->line) < 0 + || loadsection(elf, ".debug_pubnames", &d->pubnames) < 0 + || loadsection(elf, ".debug_ranges", &d->ranges) < 0 + || loadsection(elf, ".debug_str", &d->str) < 0 + || loadsection(elf, ".debug_info", &d->info) < 0) + goto err; + + /* 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); +} |