rdwarf 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +28 -0
- data/README.md +39 -0
- data/Rakefile +8 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/ext/rdwarf/depend +5 -0
- data/ext/rdwarf/extconf.rb +29 -0
- data/ext/rdwarf/libdwarf/CHANGES +102 -0
- data/ext/rdwarf/libdwarf/CODINGSTYLE +71 -0
- data/ext/rdwarf/libdwarf/COPYING +28 -0
- data/ext/rdwarf/libdwarf/ChangeLog +619 -0
- data/ext/rdwarf/libdwarf/ChangeLog2006 +835 -0
- data/ext/rdwarf/libdwarf/ChangeLog2007 +217 -0
- data/ext/rdwarf/libdwarf/ChangeLog2008 +263 -0
- data/ext/rdwarf/libdwarf/ChangeLog2009 +348 -0
- data/ext/rdwarf/libdwarf/ChangeLog2010 +175 -0
- data/ext/rdwarf/libdwarf/ChangeLog2011 +297 -0
- data/ext/rdwarf/libdwarf/ChangeLog2012 +131 -0
- data/ext/rdwarf/libdwarf/ChangeLog2013 +238 -0
- data/ext/rdwarf/libdwarf/ChangeLog2014 +399 -0
- data/ext/rdwarf/libdwarf/LGPL.txt +504 -0
- data/ext/rdwarf/libdwarf/LIBDWARFCOPYRIGHT +40 -0
- data/ext/rdwarf/libdwarf/Makefile.in +220 -0
- data/ext/rdwarf/libdwarf/NEWS +535 -0
- data/ext/rdwarf/libdwarf/README +235 -0
- data/ext/rdwarf/libdwarf/checkexamples.c +1179 -0
- data/ext/rdwarf/libdwarf/cmplrs/dwarf_addr_finder.h +55 -0
- data/ext/rdwarf/libdwarf/common.c +62 -0
- data/ext/rdwarf/libdwarf/common.h +38 -0
- data/ext/rdwarf/libdwarf/config.h.in +146 -0
- data/ext/rdwarf/libdwarf/configure +5581 -0
- data/ext/rdwarf/libdwarf/configure.in +167 -0
- data/ext/rdwarf/libdwarf/dw-linetableheader.txt +39 -0
- data/ext/rdwarf/libdwarf/dwarf.h +1342 -0
- data/ext/rdwarf/libdwarf/dwarf_abbrev.c +291 -0
- data/ext/rdwarf/libdwarf/dwarf_abbrev.h +45 -0
- data/ext/rdwarf/libdwarf/dwarf_addr_finder.c +676 -0
- data/ext/rdwarf/libdwarf/dwarf_alloc.c +685 -0
- data/ext/rdwarf/libdwarf/dwarf_alloc.h +38 -0
- data/ext/rdwarf/libdwarf/dwarf_arange.c +595 -0
- data/ext/rdwarf/libdwarf/dwarf_arange.h +62 -0
- data/ext/rdwarf/libdwarf/dwarf_base_types.h +157 -0
- data/ext/rdwarf/libdwarf/dwarf_die_deliv.c +1802 -0
- data/ext/rdwarf/libdwarf/dwarf_die_deliv.h +46 -0
- data/ext/rdwarf/libdwarf/dwarf_elf_access.c +1348 -0
- data/ext/rdwarf/libdwarf/dwarf_elf_access.h +46 -0
- data/ext/rdwarf/libdwarf/dwarf_error.c +492 -0
- data/ext/rdwarf/libdwarf/dwarf_error.h +53 -0
- data/ext/rdwarf/libdwarf/dwarf_form.c +1302 -0
- data/ext/rdwarf/libdwarf/dwarf_frame.c +2454 -0
- data/ext/rdwarf/libdwarf/dwarf_frame.h +418 -0
- data/ext/rdwarf/libdwarf/dwarf_frame2.c +1533 -0
- data/ext/rdwarf/libdwarf/dwarf_frame3.c +282 -0
- data/ext/rdwarf/libdwarf/dwarf_funcs.c +123 -0
- data/ext/rdwarf/libdwarf/dwarf_funcs.h +33 -0
- data/ext/rdwarf/libdwarf/dwarf_gdbindex.c +520 -0
- data/ext/rdwarf/libdwarf/dwarf_gdbindex.h +97 -0
- data/ext/rdwarf/libdwarf/dwarf_global.c +612 -0
- data/ext/rdwarf/libdwarf/dwarf_global.h +117 -0
- data/ext/rdwarf/libdwarf/dwarf_harmless.c +228 -0
- data/ext/rdwarf/libdwarf/dwarf_harmless.h +31 -0
- data/ext/rdwarf/libdwarf/dwarf_incl.h +61 -0
- data/ext/rdwarf/libdwarf/dwarf_init_finish.c +1263 -0
- data/ext/rdwarf/libdwarf/dwarf_leb.c +159 -0
- data/ext/rdwarf/libdwarf/dwarf_line.c +1822 -0
- data/ext/rdwarf/libdwarf/dwarf_line.h +446 -0
- data/ext/rdwarf/libdwarf/dwarf_line2.c +98 -0
- data/ext/rdwarf/libdwarf/dwarf_line_table_reader_common.c +1583 -0
- data/ext/rdwarf/libdwarf/dwarf_loc.c +1525 -0
- data/ext/rdwarf/libdwarf/dwarf_loc.h +149 -0
- data/ext/rdwarf/libdwarf/dwarf_loc2.c +833 -0
- data/ext/rdwarf/libdwarf/dwarf_macro.c +479 -0
- data/ext/rdwarf/libdwarf/dwarf_macro.h +35 -0
- data/ext/rdwarf/libdwarf/dwarf_opaque.h +778 -0
- data/ext/rdwarf/libdwarf/dwarf_original_elf_init.c +219 -0
- data/ext/rdwarf/libdwarf/dwarf_print_lines.c +631 -0
- data/ext/rdwarf/libdwarf/dwarf_pubtypes.c +132 -0
- data/ext/rdwarf/libdwarf/dwarf_query.c +1594 -0
- data/ext/rdwarf/libdwarf/dwarf_ranges.c +194 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_arm.h +308 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_mips.h +117 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_ppc.h +242 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_ppc64.h +272 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_x86_64.h +127 -0
- data/ext/rdwarf/libdwarf/dwarf_sort_line.c +665 -0
- data/ext/rdwarf/libdwarf/dwarf_string.c +82 -0
- data/ext/rdwarf/libdwarf/dwarf_stubs.c +38 -0
- data/ext/rdwarf/libdwarf/dwarf_tied.c +423 -0
- data/ext/rdwarf/libdwarf/dwarf_tsearch.h +125 -0
- data/ext/rdwarf/libdwarf/dwarf_tsearchhash.c +675 -0
- data/ext/rdwarf/libdwarf/dwarf_types.c +121 -0
- data/ext/rdwarf/libdwarf/dwarf_types.h +32 -0
- data/ext/rdwarf/libdwarf/dwarf_util.c +913 -0
- data/ext/rdwarf/libdwarf/dwarf_util.h +324 -0
- data/ext/rdwarf/libdwarf/dwarf_vars.c +125 -0
- data/ext/rdwarf/libdwarf/dwarf_vars.h +29 -0
- data/ext/rdwarf/libdwarf/dwarf_weaks.c +123 -0
- data/ext/rdwarf/libdwarf/dwarf_weaks.h +29 -0
- data/ext/rdwarf/libdwarf/dwarf_xu_index.c +579 -0
- data/ext/rdwarf/libdwarf/dwarf_xu_index.h +68 -0
- data/ext/rdwarf/libdwarf/dwgetopt.c +181 -0
- data/ext/rdwarf/libdwarf/dwgetopt.h +51 -0
- data/ext/rdwarf/libdwarf/gennames.c +531 -0
- data/ext/rdwarf/libdwarf/install.sh +119 -0
- data/ext/rdwarf/libdwarf/libdwarf.h.in +3746 -0
- data/ext/rdwarf/libdwarf/libdwarf2.1.mm +9805 -0
- data/ext/rdwarf/libdwarf/libdwarf2.1.pdf +0 -0
- data/ext/rdwarf/libdwarf/libdwarf2p.1.mm +2807 -0
- data/ext/rdwarf/libdwarf/libdwarf2p.1.pdf +0 -0
- data/ext/rdwarf/libdwarf/libdwarfdefs.h +81 -0
- data/ext/rdwarf/libdwarf/malloc_check.c +327 -0
- data/ext/rdwarf/libdwarf/malloc_check.h +52 -0
- data/ext/rdwarf/libdwarf/mips_extensions.mm +1266 -0
- data/ext/rdwarf/libdwarf/mips_extensions.pdf +0 -0
- data/ext/rdwarf/libdwarf/pro_alloc.c +179 -0
- data/ext/rdwarf/libdwarf/pro_alloc.h +33 -0
- data/ext/rdwarf/libdwarf/pro_arange.c +310 -0
- data/ext/rdwarf/libdwarf/pro_arange.h +51 -0
- data/ext/rdwarf/libdwarf/pro_die.c +431 -0
- data/ext/rdwarf/libdwarf/pro_die.h +59 -0
- data/ext/rdwarf/libdwarf/pro_encode_nm.c +108 -0
- data/ext/rdwarf/libdwarf/pro_encode_nm.h +39 -0
- data/ext/rdwarf/libdwarf/pro_error.c +96 -0
- data/ext/rdwarf/libdwarf/pro_error.h +43 -0
- data/ext/rdwarf/libdwarf/pro_expr.c +575 -0
- data/ext/rdwarf/libdwarf/pro_expr.h +36 -0
- data/ext/rdwarf/libdwarf/pro_finish.c +45 -0
- data/ext/rdwarf/libdwarf/pro_forms.c +1271 -0
- data/ext/rdwarf/libdwarf/pro_frame.c +572 -0
- data/ext/rdwarf/libdwarf/pro_frame.h +120 -0
- data/ext/rdwarf/libdwarf/pro_funcs.c +50 -0
- data/ext/rdwarf/libdwarf/pro_incl.h +91 -0
- data/ext/rdwarf/libdwarf/pro_init.c +327 -0
- data/ext/rdwarf/libdwarf/pro_line.c +373 -0
- data/ext/rdwarf/libdwarf/pro_line.h +112 -0
- data/ext/rdwarf/libdwarf/pro_macinfo.c +457 -0
- data/ext/rdwarf/libdwarf/pro_macinfo.h +31 -0
- data/ext/rdwarf/libdwarf/pro_opaque.h +513 -0
- data/ext/rdwarf/libdwarf/pro_pubnames.c +60 -0
- data/ext/rdwarf/libdwarf/pro_reloc.c +253 -0
- data/ext/rdwarf/libdwarf/pro_reloc.h +38 -0
- data/ext/rdwarf/libdwarf/pro_reloc_stream.c +256 -0
- data/ext/rdwarf/libdwarf/pro_reloc_stream.h +52 -0
- data/ext/rdwarf/libdwarf/pro_reloc_symbolic.c +245 -0
- data/ext/rdwarf/libdwarf/pro_reloc_symbolic.h +45 -0
- data/ext/rdwarf/libdwarf/pro_section.c +2233 -0
- data/ext/rdwarf/libdwarf/pro_section.h +100 -0
- data/ext/rdwarf/libdwarf/pro_types.c +274 -0
- data/ext/rdwarf/libdwarf/pro_types.h +34 -0
- data/ext/rdwarf/libdwarf/pro_util.h +38 -0
- data/ext/rdwarf/libdwarf/pro_vars.c +52 -0
- data/ext/rdwarf/libdwarf/pro_weaks.c +51 -0
- data/ext/rdwarf/rdwarf.c +765 -0
- data/ext/rdwarf/rdwarf.h +52 -0
- data/ext/rdwarf/rdwarf_names_gen.rb +109 -0
- data/lib/rdwarf.rb +181 -0
- data/lib/rdwarf/version.rb +3 -0
- data/rdwarf.gemspec +30 -0
- metadata +251 -0
@@ -0,0 +1,291 @@
|
|
1
|
+
/*
|
2
|
+
|
3
|
+
Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
|
4
|
+
Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved.
|
5
|
+
|
6
|
+
This program is free software; you can redistribute it and/or modify it
|
7
|
+
under the terms of version 2.1 of the GNU Lesser General Public License
|
8
|
+
as published by the Free Software Foundation.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it would be useful, but
|
11
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
13
|
+
|
14
|
+
Further, this software is distributed without any warranty that it is
|
15
|
+
free of the rightful claim of any third person regarding infringement
|
16
|
+
or the like. Any license provided herein, whether implied or
|
17
|
+
otherwise, applies only to this software file. Patent licenses, if
|
18
|
+
any, provided herein do not apply to combinations of this program with
|
19
|
+
other software, or any other product whatsoever.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU Lesser General Public
|
22
|
+
License along with this program; if not, write the Free Software
|
23
|
+
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
|
24
|
+
USA.
|
25
|
+
|
26
|
+
*/
|
27
|
+
|
28
|
+
#include "config.h"
|
29
|
+
#include "dwarf_incl.h"
|
30
|
+
#include <stdio.h>
|
31
|
+
#include "dwarf_abbrev.h"
|
32
|
+
|
33
|
+
/* This is used to print a .debug_abbrev section without
|
34
|
+
knowing about the DIEs that use the abbrevs.
|
35
|
+
|
36
|
+
When we have a simple .o
|
37
|
+
there is at least a hope of iterating through
|
38
|
+
the abbrevs meaningfully without knowing
|
39
|
+
a CU context.
|
40
|
+
|
41
|
+
This often fails or gets incorrect info
|
42
|
+
because there is no guarantee the .debug_abbrev
|
43
|
+
section is free of garbage bytes.
|
44
|
+
|
45
|
+
In an object with multiple CU/TUs the
|
46
|
+
output is difficult/impossible to usefully interpret.
|
47
|
+
|
48
|
+
In a dwp (Package File) it is really impossible
|
49
|
+
to associate abbrevs with a CU.
|
50
|
+
|
51
|
+
*/
|
52
|
+
|
53
|
+
int
|
54
|
+
dwarf_get_abbrev(Dwarf_Debug dbg,
|
55
|
+
Dwarf_Unsigned offset,
|
56
|
+
Dwarf_Abbrev * returned_abbrev,
|
57
|
+
Dwarf_Unsigned * length,
|
58
|
+
Dwarf_Unsigned * abbr_count, Dwarf_Error * error)
|
59
|
+
{
|
60
|
+
Dwarf_Small *abbrev_ptr = 0;
|
61
|
+
Dwarf_Small *abbrev_section_end = 0;
|
62
|
+
Dwarf_Half attr = 0;
|
63
|
+
Dwarf_Half attr_form = 0;
|
64
|
+
Dwarf_Abbrev ret_abbrev = 0;
|
65
|
+
Dwarf_Unsigned labbr_count = 0;
|
66
|
+
Dwarf_Unsigned utmp = 0;
|
67
|
+
|
68
|
+
if (dbg == NULL) {
|
69
|
+
_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
|
70
|
+
return (DW_DLV_ERROR);
|
71
|
+
}
|
72
|
+
if (dbg->de_debug_abbrev.dss_data == 0) {
|
73
|
+
/* Loads abbrev section (and .debug_info as we do those
|
74
|
+
together). */
|
75
|
+
int res = _dwarf_load_debug_info(dbg, error);
|
76
|
+
|
77
|
+
if (res != DW_DLV_OK) {
|
78
|
+
return res;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
if (offset >= dbg->de_debug_abbrev.dss_size) {
|
83
|
+
return (DW_DLV_NO_ENTRY);
|
84
|
+
}
|
85
|
+
|
86
|
+
ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1);
|
87
|
+
if (ret_abbrev == NULL) {
|
88
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
89
|
+
return (DW_DLV_ERROR);
|
90
|
+
}
|
91
|
+
ret_abbrev->ab_dbg = dbg;
|
92
|
+
if (returned_abbrev == 0 || abbr_count == 0) {
|
93
|
+
dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
|
94
|
+
_dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL);
|
95
|
+
return (DW_DLV_ERROR);
|
96
|
+
}
|
97
|
+
|
98
|
+
|
99
|
+
*abbr_count = 0;
|
100
|
+
if (length != NULL)
|
101
|
+
*length = 1;
|
102
|
+
|
103
|
+
|
104
|
+
abbrev_ptr = dbg->de_debug_abbrev.dss_data + offset;
|
105
|
+
abbrev_section_end =
|
106
|
+
dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size;
|
107
|
+
|
108
|
+
DECODE_LEB128_UWORD(abbrev_ptr, utmp);
|
109
|
+
ret_abbrev->ab_code = (Dwarf_Word) utmp;
|
110
|
+
if (ret_abbrev->ab_code == 0) {
|
111
|
+
*returned_abbrev = ret_abbrev;
|
112
|
+
*abbr_count = 0;
|
113
|
+
if (length) {
|
114
|
+
*length = 1;
|
115
|
+
}
|
116
|
+
return (DW_DLV_OK);
|
117
|
+
}
|
118
|
+
|
119
|
+
DECODE_LEB128_UWORD(abbrev_ptr, utmp);
|
120
|
+
ret_abbrev->ab_tag = utmp;
|
121
|
+
ret_abbrev->ab_has_child = *(abbrev_ptr++);
|
122
|
+
ret_abbrev->ab_abbrev_ptr = abbrev_ptr;
|
123
|
+
|
124
|
+
do {
|
125
|
+
Dwarf_Unsigned utmp2;
|
126
|
+
|
127
|
+
DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
|
128
|
+
attr = (Dwarf_Half) utmp2;
|
129
|
+
DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
|
130
|
+
attr_form = (Dwarf_Half) utmp2;
|
131
|
+
|
132
|
+
if (attr != 0)
|
133
|
+
(labbr_count)++;
|
134
|
+
|
135
|
+
} while (abbrev_ptr < abbrev_section_end &&
|
136
|
+
(attr != 0 || attr_form != 0));
|
137
|
+
|
138
|
+
if (abbrev_ptr > abbrev_section_end) {
|
139
|
+
dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
|
140
|
+
_dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
|
141
|
+
return (DW_DLV_ERROR);
|
142
|
+
}
|
143
|
+
|
144
|
+
if (length != NULL)
|
145
|
+
*length = abbrev_ptr - dbg->de_debug_abbrev.dss_data - offset;
|
146
|
+
|
147
|
+
*returned_abbrev = ret_abbrev;
|
148
|
+
*abbr_count = labbr_count;
|
149
|
+
return (DW_DLV_OK);
|
150
|
+
}
|
151
|
+
|
152
|
+
int
|
153
|
+
dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,
|
154
|
+
Dwarf_Unsigned * returned_code,
|
155
|
+
Dwarf_Error * error)
|
156
|
+
{
|
157
|
+
if (abbrev == NULL) {
|
158
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
|
159
|
+
return (DW_DLV_ERROR);
|
160
|
+
}
|
161
|
+
|
162
|
+
*returned_code = abbrev->ab_code;
|
163
|
+
return (DW_DLV_OK);
|
164
|
+
}
|
165
|
+
|
166
|
+
/* DWARF defines DW_TAG_hi_user as 0xffff so no tag should be
|
167
|
+
over 16 bits. */
|
168
|
+
int
|
169
|
+
dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,
|
170
|
+
Dwarf_Half * returned_tag, Dwarf_Error * error)
|
171
|
+
{
|
172
|
+
if (abbrev == NULL) {
|
173
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
|
174
|
+
return (DW_DLV_ERROR);
|
175
|
+
}
|
176
|
+
|
177
|
+
*returned_tag = abbrev->ab_tag;
|
178
|
+
return (DW_DLV_OK);
|
179
|
+
}
|
180
|
+
|
181
|
+
|
182
|
+
int
|
183
|
+
dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,
|
184
|
+
Dwarf_Signed * returned_flag,
|
185
|
+
Dwarf_Error * error)
|
186
|
+
{
|
187
|
+
if (abbrev == NULL) {
|
188
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
|
189
|
+
return (DW_DLV_ERROR);
|
190
|
+
}
|
191
|
+
|
192
|
+
*returned_flag = abbrev->ab_has_child;
|
193
|
+
return (DW_DLV_OK);
|
194
|
+
}
|
195
|
+
|
196
|
+
|
197
|
+
int
|
198
|
+
dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,
|
199
|
+
Dwarf_Signed indx,
|
200
|
+
Dwarf_Half * returned_attr_num,
|
201
|
+
Dwarf_Signed * form,
|
202
|
+
Dwarf_Off * offset, Dwarf_Error * error)
|
203
|
+
{
|
204
|
+
Dwarf_Byte_Ptr abbrev_ptr = 0;
|
205
|
+
Dwarf_Byte_Ptr abbrev_end = 0;
|
206
|
+
Dwarf_Byte_Ptr mark_abbrev_ptr = 0;
|
207
|
+
Dwarf_Half attr = 0;
|
208
|
+
Dwarf_Half attr_form = 0;
|
209
|
+
|
210
|
+
if (indx < 0)
|
211
|
+
return (DW_DLV_NO_ENTRY);
|
212
|
+
|
213
|
+
if (abbrev == NULL) {
|
214
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
|
215
|
+
return (DW_DLV_ERROR);
|
216
|
+
}
|
217
|
+
|
218
|
+
if (abbrev->ab_code == 0) {
|
219
|
+
return (DW_DLV_NO_ENTRY);
|
220
|
+
}
|
221
|
+
|
222
|
+
if (abbrev->ab_dbg == NULL) {
|
223
|
+
_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
|
224
|
+
return (DW_DLV_ERROR);
|
225
|
+
}
|
226
|
+
|
227
|
+
abbrev_ptr = abbrev->ab_abbrev_ptr;
|
228
|
+
abbrev_end =
|
229
|
+
abbrev->ab_dbg->de_debug_abbrev.dss_data +
|
230
|
+
abbrev->ab_dbg->de_debug_abbrev.dss_size;
|
231
|
+
|
232
|
+
for (attr = 1, attr_form = 1;
|
233
|
+
indx >= 0 && abbrev_ptr < abbrev_end && (attr != 0 ||
|
234
|
+
attr_form != 0);
|
235
|
+
indx--) {
|
236
|
+
Dwarf_Unsigned utmp4;
|
237
|
+
|
238
|
+
mark_abbrev_ptr = abbrev_ptr;
|
239
|
+
DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
|
240
|
+
attr = (Dwarf_Half) utmp4;
|
241
|
+
DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
|
242
|
+
attr_form = (Dwarf_Half) utmp4;
|
243
|
+
}
|
244
|
+
|
245
|
+
if (abbrev_ptr >= abbrev_end) {
|
246
|
+
_dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
|
247
|
+
return (DW_DLV_ERROR);
|
248
|
+
}
|
249
|
+
|
250
|
+
if (indx >= 0) {
|
251
|
+
return (DW_DLV_NO_ENTRY);
|
252
|
+
}
|
253
|
+
|
254
|
+
if (form != NULL)
|
255
|
+
*form = attr_form;
|
256
|
+
if (offset != NULL)
|
257
|
+
*offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev.dss_data;
|
258
|
+
|
259
|
+
*returned_attr_num = (attr);
|
260
|
+
return DW_DLV_OK;
|
261
|
+
}
|
262
|
+
|
263
|
+
/* This function is not entirely safe to call.
|
264
|
+
The problem is that the DWARF[234] specification does not insist
|
265
|
+
that bytes in .debug_abbrev that are not referenced by .debug_info
|
266
|
+
or .debug_types need to be initialized to anything specific.
|
267
|
+
Any garbage bytes may cause trouble. Not all compilers/linkers
|
268
|
+
leave unreferenced garbage bytes in .debug_abbrev, so this may
|
269
|
+
work for most objects. */
|
270
|
+
int
|
271
|
+
dwarf_get_abbrev_count(Dwarf_Debug dbg)
|
272
|
+
{
|
273
|
+
Dwarf_Abbrev ab;
|
274
|
+
Dwarf_Unsigned offset = 0;
|
275
|
+
Dwarf_Unsigned length = 0;
|
276
|
+
Dwarf_Unsigned attr_count = 0;
|
277
|
+
Dwarf_Unsigned abbrev_count = 0;
|
278
|
+
int abres = DW_DLV_OK;
|
279
|
+
Dwarf_Error err;
|
280
|
+
|
281
|
+
while ((abres = dwarf_get_abbrev(dbg, offset, &ab,
|
282
|
+
&length, &attr_count,
|
283
|
+
&err)) == DW_DLV_OK) {
|
284
|
+
|
285
|
+
++abbrev_count;
|
286
|
+
offset += length;
|
287
|
+
dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
|
288
|
+
}
|
289
|
+
return abbrev_count;
|
290
|
+
}
|
291
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
/*
|
2
|
+
Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved.
|
3
|
+
Portions Copyright (C) 2008-2011 David Anderson. All Rights Reserved.
|
4
|
+
|
5
|
+
This program is free software; you can redistribute it and/or modify it
|
6
|
+
under the terms of version 2.1 of the GNU Lesser General Public License
|
7
|
+
as published by the Free Software Foundation.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it would be useful, but
|
10
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
12
|
+
|
13
|
+
Further, this software is distributed without any warranty that it is
|
14
|
+
free of the rightful claim of any third person regarding infringement
|
15
|
+
or the like. Any license provided herein, whether implied or
|
16
|
+
otherwise, applies only to this software file. Patent licenses, if
|
17
|
+
any, provided herein do not apply to combinations of this program with
|
18
|
+
other software, or any other product whatsoever.
|
19
|
+
|
20
|
+
You should have received a copy of the GNU Lesser General Public
|
21
|
+
License along with this program; if not, write the Free Software
|
22
|
+
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
|
23
|
+
USA.
|
24
|
+
|
25
|
+
*/
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
/* In a given CU, one of these is (eventually) set up
|
31
|
+
for every abbreviation we need to find (and for all.
|
32
|
+
those ealier in the abbreviations for that CU).
|
33
|
+
So we don't want elements needlessly big.
|
34
|
+
*/
|
35
|
+
struct Dwarf_Abbrev_s {
|
36
|
+
/* No TAG should exceed DW_TAG_hi_user, 0xffff, but
|
37
|
+
we do allow a larger value here. */
|
38
|
+
Dwarf_Word ab_tag;
|
39
|
+
/* Abbreviations are numbered (normally sequentially from
|
40
|
+
1 and so 16 bits is not enough! */
|
41
|
+
Dwarf_Word ab_code;
|
42
|
+
Dwarf_Small ab_has_child;
|
43
|
+
Dwarf_Byte_Ptr ab_abbrev_ptr;
|
44
|
+
Dwarf_Debug ab_dbg;
|
45
|
+
};
|
@@ -0,0 +1,676 @@
|
|
1
|
+
/*
|
2
|
+
|
3
|
+
Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
|
4
|
+
Portions Copyright 2011 David Anderson. All Rights Reserved.
|
5
|
+
|
6
|
+
This program is free software; you can redistribute it and/or modify it
|
7
|
+
under the terms of version 2.1 of the GNU Lesser General Public License
|
8
|
+
as published by the Free Software Foundation.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it would be useful, but
|
11
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
13
|
+
|
14
|
+
Further, this software is distributed without any warranty that it is
|
15
|
+
free of the rightful claim of any third person regarding infringement
|
16
|
+
or the like. Any license provided herein, whether implied or
|
17
|
+
otherwise, applies only to this software file. Patent licenses, if
|
18
|
+
any, provided herein do not apply to combinations of this program with
|
19
|
+
other software, or any other product whatsoever.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU Lesser General Public
|
22
|
+
License along with this program; if not, write the Free Software
|
23
|
+
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
|
24
|
+
USA.
|
25
|
+
|
26
|
+
*/
|
27
|
+
/* This code used by SGI-IRIX rqs processing, not needed by
|
28
|
+
any other system or application.
|
29
|
+
The 'We need' and 'FIX' here are left in for historical
|
30
|
+
interest, the code is not really used in the public libdwarf
|
31
|
+
or applications.
|
32
|
+
*/
|
33
|
+
|
34
|
+
#include "config.h"
|
35
|
+
#include "libdwarfdefs.h"
|
36
|
+
#ifdef HAVE_ELF_H
|
37
|
+
#include <elf.h>
|
38
|
+
#endif
|
39
|
+
#include <dwarf.h>
|
40
|
+
#include <libdwarf.h>
|
41
|
+
#include "dwarf_base_types.h"
|
42
|
+
#include "dwarf_alloc.h"
|
43
|
+
#include "dwarf_opaque.h"
|
44
|
+
#include "dwarf_arange.h"
|
45
|
+
#include "dwarf_line.h"
|
46
|
+
#include "dwarf_frame.h"
|
47
|
+
#include <cmplrs/dwarf_addr_finder.h>
|
48
|
+
#include "dwarf_error.h"
|
49
|
+
|
50
|
+
typedef unsigned long long ull;
|
51
|
+
|
52
|
+
static int do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die,
|
53
|
+
int *errval);
|
54
|
+
static int handle_debug_info(Dwarf_Debug dbg, int *errval);
|
55
|
+
static int handle_debug_frame(Dwarf_Debug dbg,
|
56
|
+
Dwarf_addr_callback_func cb_func, int *errval);
|
57
|
+
static int handle_debug_aranges(Dwarf_Debug dbg,
|
58
|
+
Dwarf_addr_callback_func cb_func, int *errval);
|
59
|
+
static int handle_debug_line(Dwarf_Debug dbg,
|
60
|
+
Dwarf_Die cu_die, Dwarf_addr_callback_func cb_func, int *errval);
|
61
|
+
static int handle_debug_loc(void);
|
62
|
+
|
63
|
+
|
64
|
+
/* A static variable is not thread-safe, but this is only
|
65
|
+
used by SGI-internal software which is single-threaded
|
66
|
+
so the static variable is safe.
|
67
|
+
*/
|
68
|
+
static Dwarf_addr_callback_func send_addr_note;
|
69
|
+
|
70
|
+
/* A function which should probably not be used outside
|
71
|
+
of SGI. Intended to be used by executable and
|
72
|
+
shared-library post-processor software.
|
73
|
+
*/
|
74
|
+
int
|
75
|
+
_dwarf_addr_finder(dwarf_elf_handle elf_file_ptr,
|
76
|
+
Dwarf_addr_callback_func cb_func, int *dwerr)
|
77
|
+
{
|
78
|
+
|
79
|
+
Dwarf_Error err = 0;
|
80
|
+
Dwarf_Debug dbg = 0;
|
81
|
+
int res = 0;
|
82
|
+
int errval = 0;
|
83
|
+
int sections_found = 0;
|
84
|
+
|
85
|
+
res = dwarf_elf_init(elf_file_ptr, DW_DLC_READ, /* errhand */ 0,
|
86
|
+
/* errarg */ 0, &dbg, &err);
|
87
|
+
if (res == DW_DLV_ERROR) {
|
88
|
+
int errv = (int) dwarf_errno(err);
|
89
|
+
return errv;
|
90
|
+
}
|
91
|
+
if (res == DW_DLV_NO_ENTRY) {
|
92
|
+
return res;
|
93
|
+
}
|
94
|
+
send_addr_note = cb_func;
|
95
|
+
res = handle_debug_info(dbg, &errval);
|
96
|
+
switch (res) {
|
97
|
+
case DW_DLV_OK:
|
98
|
+
++sections_found;
|
99
|
+
break;
|
100
|
+
case DW_DLV_NO_ENTRY:
|
101
|
+
|
102
|
+
break;
|
103
|
+
default:
|
104
|
+
case DW_DLV_ERROR:
|
105
|
+
dwarf_finish(dbg, &err);
|
106
|
+
*dwerr = errval;
|
107
|
+
return res;
|
108
|
+
}
|
109
|
+
|
110
|
+
res = handle_debug_aranges(dbg, cb_func, &errval);
|
111
|
+
switch (res) {
|
112
|
+
case DW_DLV_OK:
|
113
|
+
++sections_found;
|
114
|
+
break;
|
115
|
+
case DW_DLV_NO_ENTRY:
|
116
|
+
break;
|
117
|
+
default:
|
118
|
+
case DW_DLV_ERROR:
|
119
|
+
dwarf_finish(dbg, &err);
|
120
|
+
*dwerr = errval;
|
121
|
+
return res;
|
122
|
+
}
|
123
|
+
res = handle_debug_frame(dbg, cb_func, &errval);
|
124
|
+
switch (res) {
|
125
|
+
case DW_DLV_OK:
|
126
|
+
++sections_found;
|
127
|
+
break;
|
128
|
+
case DW_DLV_NO_ENTRY:
|
129
|
+
break;
|
130
|
+
default:
|
131
|
+
case DW_DLV_ERROR:
|
132
|
+
dwarf_finish(dbg, &err);
|
133
|
+
*dwerr = errval;
|
134
|
+
return res;
|
135
|
+
}
|
136
|
+
|
137
|
+
res = handle_debug_loc(); /* does nothing */
|
138
|
+
switch (res) {
|
139
|
+
case DW_DLV_OK:
|
140
|
+
++sections_found;
|
141
|
+
break;
|
142
|
+
case DW_DLV_NO_ENTRY:
|
143
|
+
break;
|
144
|
+
default:
|
145
|
+
case DW_DLV_ERROR:
|
146
|
+
/* IMPOSSIBLE : handle_debug_loc cannot return this */
|
147
|
+
dwarf_finish(dbg, &err);
|
148
|
+
*dwerr = errval;
|
149
|
+
return res;
|
150
|
+
}
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
*dwerr = 0;
|
155
|
+
res = dwarf_finish(dbg, &err);
|
156
|
+
if (res == DW_DLV_ERROR) {
|
157
|
+
*dwerr = (int) dwarf_errno(err);
|
158
|
+
return DW_DLV_ERROR;
|
159
|
+
}
|
160
|
+
if (sections_found == 0) {
|
161
|
+
return DW_DLV_NO_ENTRY;
|
162
|
+
}
|
163
|
+
return DW_DLV_OK;
|
164
|
+
|
165
|
+
}
|
166
|
+
|
167
|
+
/* Return DW_DLV_OK, ERROR, or NO_ENTRY. */
|
168
|
+
static int
|
169
|
+
handle_debug_info(Dwarf_Debug dbg, int *errval)
|
170
|
+
{
|
171
|
+
Dwarf_Unsigned nxtoff = 1;
|
172
|
+
Dwarf_Unsigned hdr_length;
|
173
|
+
Dwarf_Half version_stamp;
|
174
|
+
Dwarf_Unsigned abbrev_offset;
|
175
|
+
Dwarf_Half addr_size;
|
176
|
+
Dwarf_Error err;
|
177
|
+
int terminate_now = 0;
|
178
|
+
int res = 0;
|
179
|
+
Dwarf_Die sibdie;
|
180
|
+
int sibres;
|
181
|
+
int nres = DW_DLV_OK;
|
182
|
+
|
183
|
+
|
184
|
+
for (nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp,
|
185
|
+
&abbrev_offset,
|
186
|
+
&addr_size, &nxtoff, &err);
|
187
|
+
terminate_now == 0 && nres == DW_DLV_OK;
|
188
|
+
nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp,
|
189
|
+
&abbrev_offset,
|
190
|
+
&addr_size, &nxtoff, &err)) {
|
191
|
+
|
192
|
+
Dwarf_Die curdie = 0;
|
193
|
+
|
194
|
+
/* Try to get the compilation unit die */
|
195
|
+
sibres = dwarf_siblingof(dbg, curdie, &sibdie, &err);
|
196
|
+
if (sibres == DW_DLV_OK) {
|
197
|
+
res = do_this_die_and_dealloc(dbg, sibdie, errval);
|
198
|
+
switch (res) {
|
199
|
+
case DW_DLV_OK:
|
200
|
+
break;
|
201
|
+
case DW_DLV_NO_ENTRY:
|
202
|
+
break;
|
203
|
+
default:
|
204
|
+
case DW_DLV_ERROR:
|
205
|
+
return DW_DLV_ERROR;
|
206
|
+
}
|
207
|
+
} else if (sibres == DW_DLV_ERROR) {
|
208
|
+
*errval = (int) dwarf_errno(err);
|
209
|
+
return DW_DLV_ERROR;
|
210
|
+
} else {
|
211
|
+
/* NO ENTRY! */
|
212
|
+
/* impossible? */
|
213
|
+
}
|
214
|
+
|
215
|
+
}
|
216
|
+
if (nres == DW_DLV_ERROR) {
|
217
|
+
int localerr = (int) dwarf_errno(err);
|
218
|
+
|
219
|
+
*errval = localerr;
|
220
|
+
return DW_DLV_ERROR;
|
221
|
+
}
|
222
|
+
return DW_DLV_OK;
|
223
|
+
}
|
224
|
+
|
225
|
+
static const int
|
226
|
+
might_have_addr[] = {
|
227
|
+
DW_AT_high_pc,
|
228
|
+
DW_AT_low_pc,
|
229
|
+
};
|
230
|
+
static const int might_have_locdesc[] = {
|
231
|
+
DW_AT_segment,
|
232
|
+
DW_AT_return_addr,
|
233
|
+
DW_AT_frame_base,
|
234
|
+
DW_AT_static_link,
|
235
|
+
DW_AT_data_member_location,
|
236
|
+
DW_AT_string_length,
|
237
|
+
DW_AT_location,
|
238
|
+
DW_AT_use_location,
|
239
|
+
DW_AT_vtable_elem_location,
|
240
|
+
};
|
241
|
+
|
242
|
+
/* Return DW_DLV_OK if handling this went ok.
|
243
|
+
For any FORM except DW_FORM_addr we do nothing
|
244
|
+
and return DW_DLV_OK.
|
245
|
+
For DW_FORM_ref_addr (the offset in .debug_info
|
246
|
+
of an address) we don't need to do anything
|
247
|
+
as the offsets in .debug_info do not change.
|
248
|
+
*/
|
249
|
+
static int
|
250
|
+
handle_attr_addr(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum,
|
251
|
+
Dwarf_Error * perr)
|
252
|
+
{
|
253
|
+
int res = DW_DLV_OK;
|
254
|
+
Dwarf_Off offset;
|
255
|
+
Dwarf_Addr addr;
|
256
|
+
Dwarf_Half form;
|
257
|
+
int ares;
|
258
|
+
|
259
|
+
Dwarf_Attribute attr;
|
260
|
+
|
261
|
+
ares = dwarf_attr(die, attrnum, &attr, perr);
|
262
|
+
if (ares == DW_DLV_OK) {
|
263
|
+
int formres = dwarf_whatform(attr, &form, perr);
|
264
|
+
|
265
|
+
switch (formres) {
|
266
|
+
case DW_DLV_OK:
|
267
|
+
break;
|
268
|
+
case DW_DLV_ERROR:
|
269
|
+
case DW_DLV_NO_ENTRY: /* impossible. */
|
270
|
+
return formres;
|
271
|
+
|
272
|
+
}
|
273
|
+
|
274
|
+
switch (form) {
|
275
|
+
case DW_FORM_addr:
|
276
|
+
res = dwarf_attr_offset(die, attr, &offset, perr);
|
277
|
+
if (res == DW_DLV_OK) {
|
278
|
+
ares = dwarf_formaddr(attr, &addr, perr);
|
279
|
+
if (ares == DW_DLV_OK) {
|
280
|
+
send_addr_note(DW_SECTION_INFO, offset, addr);
|
281
|
+
} else if (ares == DW_DLV_ERROR) {
|
282
|
+
return ares;
|
283
|
+
}
|
284
|
+
/* no entry: ok. */
|
285
|
+
} else {
|
286
|
+
/* NO_ENTRY is impossible. */
|
287
|
+
res = DW_DLV_ERROR;
|
288
|
+
}
|
289
|
+
break;
|
290
|
+
|
291
|
+
default:
|
292
|
+
/* Surprising FORM. An error? */
|
293
|
+
/* Do nothing */
|
294
|
+
;
|
295
|
+
}
|
296
|
+
dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
|
297
|
+
} else {
|
298
|
+
res = ares;
|
299
|
+
}
|
300
|
+
return res;
|
301
|
+
}
|
302
|
+
|
303
|
+
/* Return DW_DLV_OK if handling this went ok. */
|
304
|
+
static int
|
305
|
+
handle_attr_locdesc(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum,
|
306
|
+
Dwarf_Error * perr)
|
307
|
+
{
|
308
|
+
int retval = DW_DLV_OK;
|
309
|
+
Dwarf_Attribute attr;
|
310
|
+
Dwarf_Locdesc *llbuf;
|
311
|
+
Dwarf_Signed i;
|
312
|
+
Dwarf_Off offset;
|
313
|
+
Dwarf_Loc *locp;
|
314
|
+
unsigned int entindx;
|
315
|
+
int res;
|
316
|
+
int ares;
|
317
|
+
|
318
|
+
|
319
|
+
ares = dwarf_attr(die, attrnum, &attr, perr);
|
320
|
+
if (ares == DW_DLV_OK) {
|
321
|
+
Dwarf_Half form;
|
322
|
+
int fres = dwarf_whatform(attr, &form, perr);
|
323
|
+
|
324
|
+
if (fres == DW_DLV_OK) {
|
325
|
+
switch (form) {
|
326
|
+
case DW_FORM_block1:
|
327
|
+
case DW_FORM_block2:
|
328
|
+
case DW_FORM_block4:
|
329
|
+
/* must be location description */
|
330
|
+
res = dwarf_attr_offset(die, attr, &offset, perr);
|
331
|
+
llbuf = 0;
|
332
|
+
if (res == DW_DLV_OK) {
|
333
|
+
Dwarf_Signed count;
|
334
|
+
int lres = dwarf_loclist(attr, &llbuf, &count, perr);
|
335
|
+
if (lres != DW_DLV_OK) {
|
336
|
+
return lres;
|
337
|
+
}
|
338
|
+
if (count != 1) {
|
339
|
+
/* this cannot happen! */
|
340
|
+
/* perr? */
|
341
|
+
_dwarf_error(dbg, perr,
|
342
|
+
DW_DLE_LOCDESC_COUNT_WRONG);
|
343
|
+
retval = DW_DLV_ERROR;
|
344
|
+
return retval;
|
345
|
+
}
|
346
|
+
for (i = 0; i < count; ++i) {
|
347
|
+
unsigned int ents = llbuf[i].ld_cents;
|
348
|
+
|
349
|
+
locp = llbuf[i].ld_s;
|
350
|
+
for (entindx = 0; entindx < ents; entindx++) {
|
351
|
+
Dwarf_Loc *llocp;
|
352
|
+
|
353
|
+
llocp = locp + entindx;
|
354
|
+
if (llocp->lr_atom == DW_OP_addr) {
|
355
|
+
send_addr_note(DW_SECTION_INFO, offset +
|
356
|
+
llocp->lr_offset + 1
|
357
|
+
/* The offset is the
|
358
|
+
offset of the atom,
|
359
|
+
** and we know the
|
360
|
+
addr is 1 past it. */
|
361
|
+
, llocp->lr_number);
|
362
|
+
}
|
363
|
+
}
|
364
|
+
}
|
365
|
+
|
366
|
+
|
367
|
+
if (count > 0) {
|
368
|
+
for (i = 0; i < count; ++i) {
|
369
|
+
dwarf_dealloc(dbg, llbuf[i].ld_s,
|
370
|
+
DW_DLA_LOC_BLOCK);
|
371
|
+
}
|
372
|
+
dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
|
373
|
+
}
|
374
|
+
} else {
|
375
|
+
retval = res;
|
376
|
+
}
|
377
|
+
break;
|
378
|
+
|
379
|
+
default:
|
380
|
+
/* must be a const offset in debug_loc */
|
381
|
+
; /* do nothing */
|
382
|
+
}
|
383
|
+
dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
|
384
|
+
} /* else error or no entry */
|
385
|
+
retval = fres;
|
386
|
+
} else {
|
387
|
+
retval = ares;
|
388
|
+
}
|
389
|
+
return retval;
|
390
|
+
}
|
391
|
+
|
392
|
+
/* Return DW_DLV_OK, or DW_DLV_ERROR
|
393
|
+
|
394
|
+
Handle the addrs in a single die. */
|
395
|
+
static int
|
396
|
+
process_this_die_attrs(Dwarf_Debug dbg, Dwarf_Die newdie, int *errval)
|
397
|
+
{
|
398
|
+
Dwarf_Error err;
|
399
|
+
Dwarf_Half i;
|
400
|
+
Dwarf_Half newattrnum;
|
401
|
+
int res;
|
402
|
+
int tres;
|
403
|
+
Dwarf_Half ltag;
|
404
|
+
|
405
|
+
Dwarf_Off doff;
|
406
|
+
int doffres = dwarf_dieoffset(newdie, &doff, &err);
|
407
|
+
|
408
|
+
if (doffres != DW_DLV_OK) {
|
409
|
+
if (doffres == DW_DLV_ERROR) {
|
410
|
+
*errval = (int) dwarf_errno(err);
|
411
|
+
}
|
412
|
+
return doffres;
|
413
|
+
}
|
414
|
+
tres = dwarf_tag(newdie, <ag, &err);
|
415
|
+
if (tres != DW_DLV_OK) {
|
416
|
+
return tres;
|
417
|
+
}
|
418
|
+
if (DW_TAG_compile_unit == ltag) {
|
419
|
+
/* Because of the way the dwarf_line code works, we do lines
|
420
|
+
only per compile unit. This may turn out to be wrong if
|
421
|
+
we have lines left unconnected to a CU. of course such
|
422
|
+
lines will not, at present, be used by gnome. This is
|
423
|
+
not ideal as coded due to the dwarf_line.c issue. */
|
424
|
+
int lres = handle_debug_line(dbg, newdie, send_addr_note, errval);
|
425
|
+
if (lres == DW_DLV_ERROR) {
|
426
|
+
return lres;
|
427
|
+
}
|
428
|
+
}
|
429
|
+
|
430
|
+
for (i = 0; i < sizeof(might_have_addr) / sizeof(int); i++) {
|
431
|
+
int resattr;
|
432
|
+
Dwarf_Bool hasattr;
|
433
|
+
|
434
|
+
newattrnum = might_have_addr[i];
|
435
|
+
err = 0;
|
436
|
+
resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
|
437
|
+
if (DW_DLV_OK == resattr) {
|
438
|
+
if (hasattr) {
|
439
|
+
res = handle_attr_addr(dbg, newdie, newattrnum, &err);
|
440
|
+
if (res != DW_DLV_OK) {
|
441
|
+
*errval = (int) dwarf_errno(err);
|
442
|
+
return DW_DLV_ERROR;
|
443
|
+
}
|
444
|
+
}
|
445
|
+
} else {
|
446
|
+
if (resattr == DW_DLV_ERROR) {
|
447
|
+
*errval = (int) dwarf_errno(err);
|
448
|
+
return resattr;
|
449
|
+
}
|
450
|
+
}
|
451
|
+
}
|
452
|
+
for (i = 0; i < sizeof(might_have_locdesc) / sizeof(int); i++) {
|
453
|
+
int resattr;
|
454
|
+
Dwarf_Bool hasattr;
|
455
|
+
|
456
|
+
newattrnum = might_have_locdesc[i];
|
457
|
+
err = 0;
|
458
|
+
resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
|
459
|
+
if (DW_DLV_OK == resattr) {
|
460
|
+
if (hasattr) {
|
461
|
+
res =
|
462
|
+
handle_attr_locdesc(dbg, newdie, newattrnum, &err);
|
463
|
+
if (res != DW_DLV_OK) {
|
464
|
+
*errval = (int) dwarf_errno(err);
|
465
|
+
return DW_DLV_ERROR;
|
466
|
+
}
|
467
|
+
}
|
468
|
+
} else {
|
469
|
+
if (resattr == DW_DLV_ERROR) {
|
470
|
+
*errval = (int) dwarf_errno(err);
|
471
|
+
return resattr;
|
472
|
+
}
|
473
|
+
}
|
474
|
+
}
|
475
|
+
|
476
|
+
return DW_DLV_OK;
|
477
|
+
}
|
478
|
+
|
479
|
+
/* Handle siblings as a list,
|
480
|
+
Do children by recursing.
|
481
|
+
Effectively this is walking the tree preorder.
|
482
|
+
|
483
|
+
This dealloc's any die passed to it, so the
|
484
|
+
caller should not do that dealloc.
|
485
|
+
It seems more logical to have the one causing
|
486
|
+
the alloc to do the dealloc, but that way this
|
487
|
+
routine became a mess.
|
488
|
+
*/
|
489
|
+
static int
|
490
|
+
do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die, int *errval)
|
491
|
+
{
|
492
|
+
|
493
|
+
Dwarf_Die prevdie = 0;
|
494
|
+
Dwarf_Die newdie = die;
|
495
|
+
Dwarf_Error err = 0;
|
496
|
+
int res = 0;
|
497
|
+
int sibres = DW_DLV_OK;
|
498
|
+
int tres = DW_DLV_OK;
|
499
|
+
Dwarf_Die sibdie;
|
500
|
+
|
501
|
+
while (sibres == DW_DLV_OK) {
|
502
|
+
Dwarf_Die ch_die;
|
503
|
+
|
504
|
+
|
505
|
+
res = process_this_die_attrs(dbg, newdie, errval);
|
506
|
+
switch (res) {
|
507
|
+
case DW_DLV_OK:
|
508
|
+
break;
|
509
|
+
case DW_DLV_NO_ENTRY:
|
510
|
+
break;
|
511
|
+
default:
|
512
|
+
case DW_DLV_ERROR:
|
513
|
+
if (prevdie) {
|
514
|
+
dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
|
515
|
+
prevdie = 0;
|
516
|
+
}
|
517
|
+
return DW_DLV_ERROR;
|
518
|
+
}
|
519
|
+
|
520
|
+
tres = dwarf_child(newdie, &ch_die, &err);
|
521
|
+
|
522
|
+
if (tres == DW_DLV_OK) {
|
523
|
+
res = do_this_die_and_dealloc(dbg, ch_die, errval);
|
524
|
+
switch (res) {
|
525
|
+
case DW_DLV_OK:
|
526
|
+
break;
|
527
|
+
case DW_DLV_NO_ENTRY:
|
528
|
+
break;
|
529
|
+
default:
|
530
|
+
case DW_DLV_ERROR:
|
531
|
+
if (prevdie) {
|
532
|
+
dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
|
533
|
+
prevdie = 0;
|
534
|
+
}
|
535
|
+
return DW_DLV_ERROR;
|
536
|
+
}
|
537
|
+
} else if (tres == DW_DLV_ERROR) {
|
538
|
+
/* An error! */
|
539
|
+
*errval = (int) dwarf_errno(err);
|
540
|
+
if (prevdie) {
|
541
|
+
dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
|
542
|
+
prevdie = 0;
|
543
|
+
}
|
544
|
+
dwarf_dealloc(dbg, err, DW_DLA_ERROR);
|
545
|
+
return DW_DLV_ERROR;
|
546
|
+
} /* else was NO ENTRY */
|
547
|
+
prevdie = newdie;
|
548
|
+
sibdie = 0;
|
549
|
+
sibres = dwarf_siblingof(dbg, newdie, &sibdie, &err);
|
550
|
+
if (prevdie) {
|
551
|
+
dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
|
552
|
+
prevdie = 0;
|
553
|
+
}
|
554
|
+
newdie = sibdie;
|
555
|
+
|
556
|
+
}
|
557
|
+
if (sibres == DW_DLV_NO_ENTRY) {
|
558
|
+
return DW_DLV_OK;
|
559
|
+
}
|
560
|
+
/* error. */
|
561
|
+
*errval = (int) dwarf_errno(err);
|
562
|
+
if (prevdie) {
|
563
|
+
dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
|
564
|
+
prevdie = 0;
|
565
|
+
}
|
566
|
+
dwarf_dealloc(dbg, err, DW_DLA_ERROR);
|
567
|
+
return DW_DLV_ERROR;
|
568
|
+
|
569
|
+
}
|
570
|
+
|
571
|
+
|
572
|
+
static int
|
573
|
+
handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func,
|
574
|
+
int *errval)
|
575
|
+
{
|
576
|
+
int retval = DW_DLV_OK;
|
577
|
+
int res;
|
578
|
+
Dwarf_Error err;
|
579
|
+
Dwarf_Addr *addrlist;
|
580
|
+
Dwarf_Off *offsetlist;
|
581
|
+
Dwarf_Signed count;
|
582
|
+
int i;
|
583
|
+
|
584
|
+
res =
|
585
|
+
_dwarf_frame_address_offsets(dbg, &addrlist, &offsetlist,
|
586
|
+
&count, &err);
|
587
|
+
if (res == DW_DLV_OK) {
|
588
|
+
for (i = 0; i < count; i++) {
|
589
|
+
cb_func(DW_SECTION_FRAME, offsetlist[i], addrlist[i]);
|
590
|
+
}
|
591
|
+
dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR);
|
592
|
+
dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR);
|
593
|
+
} else if (res == DW_DLV_NO_ENTRY) {
|
594
|
+
retval = res;
|
595
|
+
} else {
|
596
|
+
*errval = (int) dwarf_errno(err);
|
597
|
+
retval = DW_DLV_ERROR;
|
598
|
+
}
|
599
|
+
return retval;
|
600
|
+
|
601
|
+
}
|
602
|
+
static int
|
603
|
+
handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func,
|
604
|
+
int *errval)
|
605
|
+
{
|
606
|
+
int retval = DW_DLV_OK;
|
607
|
+
Dwarf_Error err;
|
608
|
+
Dwarf_Addr *aranges;
|
609
|
+
Dwarf_Signed count;
|
610
|
+
int indx;
|
611
|
+
Dwarf_Off *offsets;
|
612
|
+
|
613
|
+
retval =
|
614
|
+
_dwarf_get_aranges_addr_offsets(dbg, &aranges, &offsets, &count,
|
615
|
+
&err);
|
616
|
+
if (retval == DW_DLV_OK) {
|
617
|
+
if (count == 0) {
|
618
|
+
retval = DW_DLV_NO_ENTRY;
|
619
|
+
} else {
|
620
|
+
for (indx = 0; indx < count; indx++) {
|
621
|
+
cb_func(DW_SECTION_ARANGES, offsets[indx],
|
622
|
+
aranges[indx]);
|
623
|
+
}
|
624
|
+
}
|
625
|
+
dwarf_dealloc(dbg, aranges, DW_DLA_ADDR);
|
626
|
+
dwarf_dealloc(dbg, offsets, DW_DLA_ADDR);
|
627
|
+
} else if (retval == DW_DLV_NO_ENTRY) {
|
628
|
+
; /* do nothing */
|
629
|
+
} else {
|
630
|
+
*errval = (int) dwarf_errno(err);
|
631
|
+
retval = DW_DLV_ERROR;
|
632
|
+
}
|
633
|
+
return retval;
|
634
|
+
}
|
635
|
+
static int
|
636
|
+
handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die,
|
637
|
+
Dwarf_addr_callback_func cb_func, int *errval)
|
638
|
+
{
|
639
|
+
int retval = DW_DLV_OK;
|
640
|
+
int res;
|
641
|
+
Dwarf_Error err;
|
642
|
+
Dwarf_Addr *addrlist;
|
643
|
+
Dwarf_Off *offsetlist;
|
644
|
+
Dwarf_Unsigned count;
|
645
|
+
Dwarf_Unsigned i;
|
646
|
+
|
647
|
+
res =
|
648
|
+
_dwarf_line_address_offsets(dbg, cu_die, &addrlist, &offsetlist,
|
649
|
+
&count, &err);
|
650
|
+
if (res == DW_DLV_OK) {
|
651
|
+
for (i = 0; i < count; i++) {
|
652
|
+
cb_func(DW_SECTION_LINE, offsetlist[i], addrlist[i]);
|
653
|
+
|
654
|
+
}
|
655
|
+
dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR);
|
656
|
+
dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR);
|
657
|
+
} else if (res == DW_DLV_NO_ENTRY) {
|
658
|
+
retval = res;
|
659
|
+
} else {
|
660
|
+
*errval = (int) dwarf_errno(err);
|
661
|
+
retval = DW_DLV_ERROR;
|
662
|
+
}
|
663
|
+
return retval;
|
664
|
+
}
|
665
|
+
|
666
|
+
/* We need to add support for this. Currently we do not
|
667
|
+
generate this section.
|
668
|
+
FIX!
|
669
|
+
*/
|
670
|
+
static int
|
671
|
+
handle_debug_loc(void)
|
672
|
+
{
|
673
|
+
int retval = DW_DLV_NO_ENTRY;
|
674
|
+
|
675
|
+
return retval;
|
676
|
+
}
|