rdwarf 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|