rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 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 | } |
| 63 | |