blob: 212995881c2e6a6ce4bb31d54080c079ca0b7283 [file] [log] [blame]
rsca84cbb22004-04-19 19:29:25 +00001/*
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
11int
12dwarfaddrtounit(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