Blob


1 /*
2 * Dwarf address ranges parsing code.
3 */
5 #include <u.h>
6 #include <libc.h>
7 #include <bio.h>
8 #include "elf.h"
9 #include "dwarf.h"
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;
19 memset(&b, 0, sizeof b);
20 b.d = d;
21 b.p = d->aranges.data;
22 b.ep = b.p + d->aranges.len;
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 }