plan9port

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

dwarfaranges.c (1318B)


      1 /*
      2  * Dwarf address ranges parsing code.
      3  */
      4 
      5 #include <u.h>
      6 #include <libc.h>
      7 #include <bio.h>
      8 #include "elf.h"
      9 #include "dwarf.h"
     10 
     11 int
     12 dwarfaddrtounit(Dwarf *d, ulong addr, ulong *unit)
     13 {
     14 	DwarfBuf b;
     15 	int segsize, i;
     16 	ulong len, id, off, base, size;
     17 	uchar *start, *end;
     18 
     19 	memset(&b, 0, sizeof b);
     20 	b.d = d;
     21 	b.p = d->aranges.data;
     22 	b.ep = b.p + d->aranges.len;
     23 
     24 	while(b.p < b.ep){
     25 		start = b.p;
     26 		len = dwarfget4(&b);
     27 		if((id = dwarfget2(&b)) != 2){
     28 			if(b.p == nil){
     29 			underflow:
     30 				werrstr("buffer underflow reading address ranges header");
     31 			}else
     32 				werrstr("bad dwarf version 0x%lux in address ranges header", id);
     33 			return -1;
     34 		}
     35 		off = dwarfget4(&b);
     36 		b.addrsize = dwarfget1(&b);
     37 		if(d->addrsize == 0)
     38 			d->addrsize = b.addrsize;
     39 		segsize = dwarfget1(&b);
     40 		USED(segsize);	/* what am i supposed to do with this? */
     41 		if(b.p == nil)
     42 			goto underflow;
     43 		if((i = (b.p-start) % (2*b.addrsize)) != 0)
     44 			b.p += 2*b.addrsize - i;
     45 		end = start+4+len;
     46 		while(b.p!=nil && b.p<end){
     47 			base = dwarfgetaddr(&b);
     48 			size = dwarfgetaddr(&b);
     49 			if(b.p == nil)
     50 				goto underflow;
     51 			if(base <= addr && addr < base+size){
     52 				*unit = off;
     53 				return 0;
     54 			}
     55 		}
     56 		if(b.p == nil)
     57 			goto underflow;
     58 		b.p = end;
     59 	}
     60 	werrstr("address 0x%lux is not listed in dwarf debugging symbols", addr);
     61 	return -1;
     62 }