|  | /* | 
|  | * Dwarf address ranges parsing code. | 
|  | */ | 
|  |  | 
|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <bio.h> | 
|  | #include "elf.h" | 
|  | #include "dwarf.h" | 
|  |  | 
|  | int | 
|  | dwarfaddrtounit(Dwarf *d, ulong addr, ulong *unit) | 
|  | { | 
|  | DwarfBuf b; | 
|  | int segsize, i; | 
|  | ulong len, id, off, base, size; | 
|  | uchar *start, *end; | 
|  |  | 
|  | memset(&b, 0, sizeof b); | 
|  | b.d = d; | 
|  | b.p = d->aranges.data; | 
|  | b.ep = b.p + d->aranges.len; | 
|  |  | 
|  | while(b.p < b.ep){ | 
|  | start = b.p; | 
|  | len = dwarfget4(&b); | 
|  | if((id = dwarfget2(&b)) != 2){ | 
|  | if(b.p == nil){ | 
|  | underflow: | 
|  | werrstr("buffer underflow reading address ranges header"); | 
|  | }else | 
|  | werrstr("bad dwarf version 0x%lux in address ranges header", id); | 
|  | return -1; | 
|  | } | 
|  | off = dwarfget4(&b); | 
|  | b.addrsize = dwarfget1(&b); | 
|  | if(d->addrsize == 0) | 
|  | d->addrsize = b.addrsize; | 
|  | segsize = dwarfget1(&b); | 
|  | USED(segsize);	/* what am i supposed to do with this? */ | 
|  | if(b.p == nil) | 
|  | goto underflow; | 
|  | if((i = (b.p-start) % (2*b.addrsize)) != 0) | 
|  | b.p += 2*b.addrsize - i; | 
|  | end = start+4+len; | 
|  | while(b.p!=nil && b.p<end){ | 
|  | base = dwarfgetaddr(&b); | 
|  | size = dwarfgetaddr(&b); | 
|  | if(b.p == nil) | 
|  | goto underflow; | 
|  | if(base <= addr && addr < base+size){ | 
|  | *unit = off; | 
|  | return 0; | 
|  | } | 
|  | } | 
|  | if(b.p == nil) | 
|  | goto underflow; | 
|  | b.p = end; | 
|  | } | 
|  | werrstr("address 0x%lux is not listed in dwarf debugging symbols", addr); | 
|  | return -1; | 
|  | } | 
|  |  |