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 }