aboutsummaryrefslogtreecommitdiff
path: root/src/libmach/dwarfopen.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-04-19 19:29:25 +0000
committerrsc <devnull@localhost>2004-04-19 19:29:25 +0000
commita84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46 (patch)
tree59a0e921597e5aa53e83d487c16727a7bf01547a /src/libmach/dwarfopen.c
parent0e3cc9f456ea49919459bf1164d0c8309a6134fa (diff)
downloadplan9port-a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46.tar.gz
plan9port-a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46.tar.bz2
plan9port-a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46.zip
libmach
Diffstat (limited to 'src/libmach/dwarfopen.c')
-rw-r--r--src/libmach/dwarfopen.c107
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);
+}