1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "elf.h"
#include "dwarf.h"
static int
readblock(int fd, DwarfBlock *b, ulong off, ulong len)
{
b->data = malloc(len);
if(b->data == nil)
return -1;
if(seek(fd, off, 0) < 0 || readn(fd, b->data, len) != len){
free(b->data);
b->data = nil;
return -1;
}
b->len = len;
return 0;
}
static int
findsection(Elf *elf, char *name, ulong *off, ulong *len)
{
ElfSect *s;
if((s = elfsection(elf, name)) == nil)
return -1;
*off = s->offset;
*len = s->size;
return s - elf->sect;
}
static int
loadsection(Elf *elf, char *name, DwarfBlock *b)
{
ulong off, len;
if(findsection(elf, name, &off, &len) < 0)
return -1;
return readblock(elf->fd, b, off, len);
}
Dwarf*
dwarfopen(Elf *elf)
{
Dwarf *d;
if(elf == nil){
werrstr("nil elf passed to dwarfopen");
return nil;
}
d = mallocz(sizeof(Dwarf), 1);
if(d == nil)
return nil;
d->elf = elf;
if(loadsection(elf, ".debug_abbrev", &d->abbrev) < 0
|| loadsection(elf, ".debug_aranges", &d->aranges) < 0
|| loadsection(elf, ".debug_line", &d->line) < 0
|| loadsection(elf, ".debug_pubnames", &d->pubnames) < 0
|| loadsection(elf, ".debug_info", &d->info) < 0)
goto err;
loadsection(elf, ".debug_frame", &d->frame);
loadsection(elf, ".debug_ranges", &d->ranges);
loadsection(elf, ".debug_str", &d->str);
/* make this a table once there are more */
switch(d->elf->hdr.machine){
case ElfMach386:
d->reg = dwarf386regs;
d->nreg = dwarf386nregs;
break;
default:
werrstr("unsupported machine");
goto err;
}
return d;
err:
free(d->abbrev.data);
free(d->aranges.data);
free(d->frame.data);
free(d->line.data);
free(d->pubnames.data);
free(d->ranges.data);
free(d->str.data);
free(d->info.data);
free(d);
return nil;
}
void
dwarfclose(Dwarf *d)
{
free(d->abbrev.data);
free(d->aranges.data);
free(d->frame.data);
free(d->line.data);
free(d->pubnames.data);
free(d->ranges.data);
free(d->str.data);
free(d->info.data);
free(d);
}
|