plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

dwarfopen.c (2000B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <bio.h>
      4 #include "elf.h"
      5 #include "dwarf.h"
      6 
      7 static int
      8 readblock(int fd, DwarfBlock *b, ulong off, ulong len)
      9 {
     10 	b->data = malloc(len);
     11 	if(b->data == nil)
     12 		return -1;
     13 	if(seek(fd, off, 0) < 0 || readn(fd, b->data, len) != len){
     14 		free(b->data);
     15 		b->data = nil;
     16 		return -1;
     17 	}
     18 	b->len = len;
     19 	return 0;
     20 }
     21 
     22 static int
     23 findsection(Elf *elf, char *name, ulong *off, ulong *len)
     24 {
     25 	ElfSect *s;
     26 
     27 	if((s = elfsection(elf, name)) == nil)
     28 		return -1;
     29 	*off = s->offset;
     30 	*len = s->size;
     31 	return s - elf->sect;
     32 }
     33 
     34 static int
     35 loadsection(Elf *elf, char *name, DwarfBlock *b)
     36 {
     37 	ulong off, len;
     38 
     39 	if(findsection(elf, name, &off, &len) < 0)
     40 		return -1;
     41 	return readblock(elf->fd, b, off, len);
     42 }
     43 
     44 Dwarf*
     45 dwarfopen(Elf *elf)
     46 {
     47 	Dwarf *d;
     48 
     49 	if(elf == nil){
     50 		werrstr("nil elf passed to dwarfopen");
     51 		return nil;
     52 	}
     53 
     54 	d = mallocz(sizeof(Dwarf), 1);
     55 	if(d == nil)
     56 		return nil;
     57 
     58 	d->elf = elf;
     59 	if(loadsection(elf, ".debug_abbrev", &d->abbrev) < 0
     60 	|| loadsection(elf, ".debug_aranges", &d->aranges) < 0
     61 	|| loadsection(elf, ".debug_line", &d->line) < 0
     62 	|| loadsection(elf, ".debug_pubnames", &d->pubnames) < 0
     63 	|| loadsection(elf, ".debug_info", &d->info) < 0)
     64 		goto err;
     65 	loadsection(elf, ".debug_frame", &d->frame);
     66 	loadsection(elf, ".debug_ranges", &d->ranges);
     67 	loadsection(elf, ".debug_str", &d->str);
     68 
     69 	/* make this a table once there are more */
     70 	switch(d->elf->hdr.machine){
     71 	case ElfMach386:
     72 		d->reg = dwarf386regs;
     73 		d->nreg = dwarf386nregs;
     74 		break;
     75 	default:
     76 		werrstr("unsupported machine");
     77 		goto err;
     78 	}
     79 
     80 	return d;
     81 
     82 err:
     83 	free(d->abbrev.data);
     84 	free(d->aranges.data);
     85 	free(d->frame.data);
     86 	free(d->line.data);
     87 	free(d->pubnames.data);
     88 	free(d->ranges.data);
     89 	free(d->str.data);
     90 	free(d->info.data);
     91 	free(d);
     92 	return nil;
     93 }
     94 
     95 void
     96 dwarfclose(Dwarf *d)
     97 {
     98 	free(d->abbrev.data);
     99 	free(d->aranges.data);
    100 	free(d->frame.data);
    101 	free(d->line.data);
    102 	free(d->pubnames.data);
    103 	free(d->ranges.data);
    104 	free(d->str.data);
    105 	free(d->info.data);
    106 	free(d);
    107 }