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,149 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Reserved.
|
|
3
|
+
Portions Copyright (C) 2015-2015 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
|
+
typedef struct Dwarf_Loc_Chain_s *Dwarf_Loc_Chain;
|
|
27
|
+
struct Dwarf_Loc_Chain_s {
|
|
28
|
+
Dwarf_Small lc_atom;
|
|
29
|
+
Dwarf_Unsigned lc_number;
|
|
30
|
+
Dwarf_Unsigned lc_number2;
|
|
31
|
+
Dwarf_Unsigned lc_number3;
|
|
32
|
+
Dwarf_Unsigned lc_offset;
|
|
33
|
+
Dwarf_Unsigned lc_opnumber;
|
|
34
|
+
Dwarf_Loc_Chain lc_next;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
/* Contains info on an uninterpreted block of data
|
|
39
|
+
Used with certain frame information functions.
|
|
40
|
+
*/
|
|
41
|
+
typedef struct {
|
|
42
|
+
Dwarf_Unsigned bl_len; /* length of block bl_data points at */
|
|
43
|
+
Dwarf_Ptr bl_data; /* uninterpreted data */
|
|
44
|
+
|
|
45
|
+
/* 0 if location description,
|
|
46
|
+
1 if .debug_info loclist,
|
|
47
|
+
2 if .debug_info.dwo split dwarf loclist. */
|
|
48
|
+
Dwarf_Small bl_from_loclist;
|
|
49
|
+
|
|
50
|
+
/* Section (not CU) offset which 'data' comes from. */
|
|
51
|
+
Dwarf_Unsigned bl_section_offset;
|
|
52
|
+
|
|
53
|
+
/* Section offset where the location description itself starts.
|
|
54
|
+
So a few bytes lower than bl_section_offset */
|
|
55
|
+
Dwarf_Unsigned bl_locdesc_offset;
|
|
56
|
+
} Dwarf_Block_c;
|
|
57
|
+
|
|
58
|
+
/* Location record. Records up to 3 operand values.
|
|
59
|
+
For DWARF5 ops with a 1 byte size and then a block
|
|
60
|
+
of data of that size we the size in an operand
|
|
61
|
+
and follow that with the next operand as a
|
|
62
|
+
pointer to the block. The pointer is inserted
|
|
63
|
+
via cast, so an ugly hack.
|
|
64
|
+
This struct is opaque. Not visible to callers.
|
|
65
|
+
*/
|
|
66
|
+
struct Dwarf_Loc_c_s {
|
|
67
|
+
Dwarf_Small lr_atom; /* Location operation */
|
|
68
|
+
|
|
69
|
+
Dwarf_Unsigned lr_number; /* First operand */
|
|
70
|
+
|
|
71
|
+
/* Second operand.
|
|
72
|
+
For OP_bregx, OP_bit_piece, OP_[GNU_]const_type,
|
|
73
|
+
OP_[GNU_]deref_type, OP_[GNU_]entry_value, OP_implicit_value,
|
|
74
|
+
OP_[GNU_]implicit_pointer, OP_[GNU_]regval_type,
|
|
75
|
+
OP_xderef_type, */
|
|
76
|
+
Dwarf_Unsigned lr_number2;
|
|
77
|
+
|
|
78
|
+
/* Third Operand.
|
|
79
|
+
For OP_[GNU_]const type, pointer to
|
|
80
|
+
block of length 'lr_number2' */
|
|
81
|
+
Dwarf_Unsigned lr_number3;
|
|
82
|
+
|
|
83
|
+
/* The number assigned. 0 to the number-of-ops - 1 in
|
|
84
|
+
the expression we are expanding. */
|
|
85
|
+
Dwarf_Unsigned lr_opnumber;
|
|
86
|
+
Dwarf_Unsigned lr_offset; /* offset in locexpr for OP_BRA etc */
|
|
87
|
+
Dwarf_Loc_c lr_next; /* When a list is useful. */
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/* Location description DWARF 2,3,4,5
|
|
91
|
+
Adds the DW_LLE value (new in DWARF5).
|
|
92
|
+
This struct is opaque. Not visible to callers. */
|
|
93
|
+
struct Dwarf_Locdesc_c_s {
|
|
94
|
+
/* The DW_LLE value of the entry. Synthesized
|
|
95
|
+
by libdwarf in a non-split-dwarf loclist,
|
|
96
|
+
recorded in a split dwarf loclist. */
|
|
97
|
+
Dwarf_Small ld_lle_value;
|
|
98
|
+
|
|
99
|
+
/* Beginning of active range. This is actually an offset
|
|
100
|
+
of an applicable base address, not a pc value. */
|
|
101
|
+
Dwarf_Addr ld_lopc;
|
|
102
|
+
|
|
103
|
+
/* End of active range. This is actually an offset
|
|
104
|
+
of an applicable base address, or a length, never a pc value. */
|
|
105
|
+
Dwarf_Addr ld_hipc; /* end of active range */
|
|
106
|
+
|
|
107
|
+
/* count of struct Dwarf_Loc_c_s in array. */
|
|
108
|
+
Dwarf_Half ld_cents;
|
|
109
|
+
/* pointer to array of struct Dwarf_Loc_c_s*/
|
|
110
|
+
Dwarf_Loc_c ld_s;
|
|
111
|
+
|
|
112
|
+
Dwarf_Small ld_from_loclist;
|
|
113
|
+
|
|
114
|
+
/* Section (not CU) offset where loc-expr begins*/
|
|
115
|
+
Dwarf_Unsigned ld_section_offset;
|
|
116
|
+
|
|
117
|
+
/* Section (not CU) offset where location descr begins*/
|
|
118
|
+
Dwarf_Unsigned ld_locdesc_offset;
|
|
119
|
+
|
|
120
|
+
/* Pointer to our header (in which we are located). */
|
|
121
|
+
Dwarf_Loc_Head_c ld_loclist_head;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/* A 'header' to the loclist and the
|
|
125
|
+
location description(s) attached to an attribute.
|
|
126
|
+
This struct is opaque. Not visible to callers. */
|
|
127
|
+
struct Dwarf_Loc_Head_c_s {
|
|
128
|
+
|
|
129
|
+
/* The array (1 or more entries) of
|
|
130
|
+
struct Loc_Desc_c_s
|
|
131
|
+
If 1 it may really be a locexpr */
|
|
132
|
+
Dwarf_Locdesc_c ll_locdesc;
|
|
133
|
+
/* Entry count of the ll_locdesc array. */
|
|
134
|
+
Dwarf_Unsigned ll_locdesc_count;
|
|
135
|
+
|
|
136
|
+
/* 0 if locexpr (in which case ll_locdesc_count is 1),
|
|
137
|
+
1 if non-split (dwarf 2,3,4) .debug_loc,
|
|
138
|
+
2 if split-dwarf .debug_loc.dwo */
|
|
139
|
+
Dwarf_Small ll_from_loclist;
|
|
140
|
+
|
|
141
|
+
/* The CU Context of this loclist or locexpr. */
|
|
142
|
+
Dwarf_CU_Context ll_context;
|
|
143
|
+
|
|
144
|
+
Dwarf_Debug ll_dbg;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
int _dwarf_loc_block_sanity_check(Dwarf_Debug dbg,
|
|
148
|
+
Dwarf_Block_c *loc_block,Dwarf_Error*error);
|
|
149
|
+
|
|
@@ -0,0 +1,833 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
|
|
3
|
+
Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved.
|
|
4
|
+
Portions Copyright (C) 2010-2012 SN Systems Ltd. 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
|
+
int
|
|
29
|
+
_dwarf_loc_block_sanity_check(Dwarf_Debug dbg,
|
|
30
|
+
Dwarf_Block_c *loc_block,Dwarf_Error* error)
|
|
31
|
+
{
|
|
32
|
+
if (loc_block->bl_from_loclist) {
|
|
33
|
+
Dwarf_Small *loc_ptr = 0;
|
|
34
|
+
Dwarf_Unsigned loc_len = 0;
|
|
35
|
+
Dwarf_Small *end_ptr = 0;
|
|
36
|
+
|
|
37
|
+
loc_ptr = loc_block->bl_data;
|
|
38
|
+
loc_len = loc_block->bl_len;
|
|
39
|
+
end_ptr = dbg->de_debug_loc.dss_size +
|
|
40
|
+
dbg->de_debug_loc.dss_data;
|
|
41
|
+
if ((loc_ptr +loc_len) > end_ptr) {
|
|
42
|
+
_dwarf_error(dbg,error,DW_DLE_DEBUG_LOC_SECTION_SHORT);
|
|
43
|
+
return DW_DLV_ERROR;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return DW_DLV_OK;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* #included in dwarf_loc.c to compile.
|
|
50
|
+
This in a separate file to make it easy to
|
|
51
|
+
see the early (pre _c) and current (_c) versions
|
|
52
|
+
at the same time (in distinct windows).
|
|
53
|
+
|
|
54
|
+
This synthesizes the ld_lle_value of the locdesc,
|
|
55
|
+
but when it is an actual dwo this value gets
|
|
56
|
+
overridden by our caller with the true ld_lle_value. */
|
|
57
|
+
|
|
58
|
+
static int
|
|
59
|
+
_dwarf_get_locdesc_c(Dwarf_Debug dbg,
|
|
60
|
+
Dwarf_Unsigned locdesc_index,
|
|
61
|
+
Dwarf_Loc_Head_c loc_head,
|
|
62
|
+
Dwarf_Block_c * loc_block,
|
|
63
|
+
Dwarf_Half address_size,
|
|
64
|
+
Dwarf_Half offset_size,
|
|
65
|
+
Dwarf_Small version_stamp,
|
|
66
|
+
Dwarf_Addr lowpc,
|
|
67
|
+
Dwarf_Addr highpc,
|
|
68
|
+
Dwarf_Error * error)
|
|
69
|
+
{
|
|
70
|
+
/* Offset of current operator from start of block. */
|
|
71
|
+
Dwarf_Unsigned offset = 0;
|
|
72
|
+
|
|
73
|
+
/* Used to chain the Dwarf_Loc_Chain_s structs. */
|
|
74
|
+
Dwarf_Loc_Chain new_loc = NULL;
|
|
75
|
+
Dwarf_Loc_Chain prev_loc = NULL;
|
|
76
|
+
Dwarf_Loc_Chain head_loc = NULL;
|
|
77
|
+
|
|
78
|
+
Dwarf_Unsigned op_count = 0;
|
|
79
|
+
|
|
80
|
+
/* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */
|
|
81
|
+
Dwarf_Loc_c block_loc = 0;
|
|
82
|
+
|
|
83
|
+
Dwarf_Locdesc_c locdesc = loc_head->ll_locdesc + locdesc_index;
|
|
84
|
+
|
|
85
|
+
Dwarf_Unsigned i = 0;
|
|
86
|
+
int res = 0;
|
|
87
|
+
|
|
88
|
+
/* ***** BEGIN CODE ***** */
|
|
89
|
+
res = _dwarf_loc_block_sanity_check(dbg,loc_block,error);
|
|
90
|
+
if (res != DW_DLV_OK) {
|
|
91
|
+
return res;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* New loop getting Loc operators. Non DWO */
|
|
95
|
+
while (offset <= loc_block->bl_len) {
|
|
96
|
+
Dwarf_Unsigned nextoffset = 0;
|
|
97
|
+
struct Dwarf_Loc_c_s temp_loc;
|
|
98
|
+
|
|
99
|
+
res = _dwarf_read_loc_expr_op(dbg,loc_block,
|
|
100
|
+
op_count,
|
|
101
|
+
version_stamp,
|
|
102
|
+
offset_size,
|
|
103
|
+
address_size,
|
|
104
|
+
offset,
|
|
105
|
+
&nextoffset,
|
|
106
|
+
&temp_loc,
|
|
107
|
+
error);
|
|
108
|
+
if (res == DW_DLV_ERROR) {
|
|
109
|
+
return res;
|
|
110
|
+
}
|
|
111
|
+
if (res == DW_DLV_NO_ENTRY) {
|
|
112
|
+
/* Normal end. */
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
op_count++;
|
|
116
|
+
new_loc =
|
|
117
|
+
(Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN, 1);
|
|
118
|
+
if (new_loc == NULL) {
|
|
119
|
+
/* Some memory may leak here. */
|
|
120
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
121
|
+
return DW_DLV_ERROR;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* Copying all the fields. DWARF 2,3,4,5. */
|
|
125
|
+
new_loc->lc_atom = temp_loc.lr_atom;
|
|
126
|
+
new_loc->lc_opnumber= temp_loc.lr_opnumber;
|
|
127
|
+
new_loc->lc_number = temp_loc.lr_number;
|
|
128
|
+
new_loc->lc_number2 = temp_loc.lr_number2;
|
|
129
|
+
new_loc->lc_number3 = temp_loc.lr_number3;
|
|
130
|
+
new_loc->lc_offset = temp_loc.lr_offset;
|
|
131
|
+
offset = nextoffset;
|
|
132
|
+
|
|
133
|
+
if (head_loc == NULL)
|
|
134
|
+
head_loc = prev_loc = new_loc;
|
|
135
|
+
else {
|
|
136
|
+
prev_loc->lc_next = new_loc;
|
|
137
|
+
prev_loc = new_loc;
|
|
138
|
+
}
|
|
139
|
+
offset = nextoffset;
|
|
140
|
+
}
|
|
141
|
+
block_loc =
|
|
142
|
+
(Dwarf_Loc_c ) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK_C,
|
|
143
|
+
op_count);
|
|
144
|
+
if (block_loc == NULL) {
|
|
145
|
+
/* Some memory does leak here. */
|
|
146
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
147
|
+
return DW_DLV_ERROR;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
new_loc = head_loc;
|
|
151
|
+
for (i = 0; i < op_count; i++) {
|
|
152
|
+
/* Copying only the fields needed by DWARF 2,3,4 */
|
|
153
|
+
(block_loc + i)->lr_atom = new_loc->lc_atom;
|
|
154
|
+
(block_loc + i)->lr_number = new_loc->lc_number;
|
|
155
|
+
(block_loc + i)->lr_number2 = new_loc->lc_number2;
|
|
156
|
+
(block_loc + i)->lr_number3 = new_loc->lc_number3;
|
|
157
|
+
(block_loc + i)->lr_offset = new_loc->lc_offset;
|
|
158
|
+
(block_loc + i)->lr_opnumber = new_loc->lc_opnumber;
|
|
159
|
+
prev_loc = new_loc;
|
|
160
|
+
new_loc = prev_loc->lc_next;
|
|
161
|
+
dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
|
|
162
|
+
}
|
|
163
|
+
/* Synthesizing the DW_LLE values. */
|
|
164
|
+
if(highpc == 0 && lowpc == 0) {
|
|
165
|
+
locdesc->ld_lle_value = DW_LLE_end_of_list_entry;
|
|
166
|
+
} else if(lowpc == MAX_ADDR) {
|
|
167
|
+
locdesc->ld_lle_value = DW_LLE_base_address_selection_entry;
|
|
168
|
+
} else {
|
|
169
|
+
locdesc->ld_lle_value = DW_LLE_offset_pair_entry;
|
|
170
|
+
}
|
|
171
|
+
locdesc->ld_cents = op_count;
|
|
172
|
+
locdesc->ld_s = block_loc;
|
|
173
|
+
locdesc->ld_from_loclist = loc_block->bl_from_loclist;
|
|
174
|
+
locdesc->ld_section_offset = loc_block->bl_section_offset;
|
|
175
|
+
locdesc->ld_locdesc_offset = loc_block->bl_locdesc_offset;
|
|
176
|
+
locdesc->ld_lopc = lowpc;
|
|
177
|
+
locdesc->ld_hipc = highpc;
|
|
178
|
+
return DW_DLV_OK;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
static int
|
|
183
|
+
_dwarf_read_loc_section_dwo(Dwarf_Debug dbg,
|
|
184
|
+
Dwarf_Block_c * return_block,
|
|
185
|
+
Dwarf_Addr * lowpc,
|
|
186
|
+
Dwarf_Addr * highpc,
|
|
187
|
+
Dwarf_Bool *at_end,
|
|
188
|
+
Dwarf_Half * lle_op,
|
|
189
|
+
Dwarf_Off sec_offset,
|
|
190
|
+
Dwarf_Half address_size,
|
|
191
|
+
Dwarf_Error * error)
|
|
192
|
+
{
|
|
193
|
+
Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset;
|
|
194
|
+
Dwarf_Small *locptr = 0;
|
|
195
|
+
Dwarf_Small llecode = 0;
|
|
196
|
+
Dwarf_Word leb128_length = 0;
|
|
197
|
+
Dwarf_Unsigned expr_offset = sec_offset;
|
|
198
|
+
|
|
199
|
+
if (sec_offset >= dbg->de_debug_loc.dss_size) {
|
|
200
|
+
/* We're at the end. No more present. */
|
|
201
|
+
return DW_DLV_NO_ENTRY;
|
|
202
|
+
}
|
|
203
|
+
memset(return_block,0,sizeof(*return_block));
|
|
204
|
+
|
|
205
|
+
/* not the same as non-split loclist, but still a list. */
|
|
206
|
+
return_block->bl_from_loclist = 2;
|
|
207
|
+
|
|
208
|
+
return_block->bl_locdesc_offset = sec_offset;
|
|
209
|
+
llecode = *beg;
|
|
210
|
+
locptr = beg +1;
|
|
211
|
+
expr_offset++;
|
|
212
|
+
switch(llecode) {
|
|
213
|
+
case DW_LLE_end_of_list_entry:
|
|
214
|
+
*at_end = TRUE;
|
|
215
|
+
return_block->bl_section_offset = expr_offset;
|
|
216
|
+
expr_offset++;
|
|
217
|
+
break;
|
|
218
|
+
case DW_LLE_base_address_selection_entry: {
|
|
219
|
+
Dwarf_Unsigned addr_index = 0;
|
|
220
|
+
|
|
221
|
+
addr_index = _dwarf_decode_u_leb128(locptr, &leb128_length);
|
|
222
|
+
locptr += leb128_length;
|
|
223
|
+
return_block->bl_section_offset = expr_offset;
|
|
224
|
+
/* So this behaves much like non-dwo loclist */
|
|
225
|
+
*lowpc=MAX_ADDR;
|
|
226
|
+
*highpc=addr_index;
|
|
227
|
+
}
|
|
228
|
+
break;
|
|
229
|
+
case DW_LLE_start_end_entry: {
|
|
230
|
+
Dwarf_Unsigned addr_indexs = 0;
|
|
231
|
+
Dwarf_Unsigned addr_indexe= 0;
|
|
232
|
+
Dwarf_Half exprlen = 0;
|
|
233
|
+
|
|
234
|
+
addr_indexs= _dwarf_decode_u_leb128(locptr, &leb128_length);
|
|
235
|
+
locptr += leb128_length;
|
|
236
|
+
expr_offset += leb128_length;
|
|
237
|
+
addr_indexe= _dwarf_decode_u_leb128(locptr, &leb128_length);
|
|
238
|
+
locptr += leb128_length;
|
|
239
|
+
expr_offset +=leb128_length;
|
|
240
|
+
|
|
241
|
+
*lowpc=addr_indexs;
|
|
242
|
+
*highpc=addr_indexe;
|
|
243
|
+
|
|
244
|
+
READ_UNALIGNED(dbg, exprlen, Dwarf_Half, locptr,
|
|
245
|
+
sizeof(exprlen));
|
|
246
|
+
locptr += sizeof(exprlen);
|
|
247
|
+
expr_offset += sizeof(exprlen);
|
|
248
|
+
|
|
249
|
+
return_block->bl_len = exprlen;
|
|
250
|
+
return_block->bl_data = locptr;
|
|
251
|
+
return_block->bl_section_offset = expr_offset;
|
|
252
|
+
|
|
253
|
+
expr_offset += exprlen;
|
|
254
|
+
if (expr_offset > dbg->de_debug_loc.dss_size) {
|
|
255
|
+
|
|
256
|
+
_dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
|
|
257
|
+
return DW_DLV_ERROR;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
break;
|
|
261
|
+
case DW_LLE_start_length_entry: {
|
|
262
|
+
Dwarf_Unsigned addr_index = 0;
|
|
263
|
+
Dwarf_ufixed range_length = 0;
|
|
264
|
+
Dwarf_Half exprlen = 0;
|
|
265
|
+
|
|
266
|
+
addr_index= _dwarf_decode_u_leb128(locptr, &leb128_length);
|
|
267
|
+
locptr += leb128_length;
|
|
268
|
+
expr_offset +=leb128_length;
|
|
269
|
+
|
|
270
|
+
READ_UNALIGNED(dbg, range_length, Dwarf_ufixed, locptr,
|
|
271
|
+
sizeof(range_length));
|
|
272
|
+
locptr += sizeof(range_length);
|
|
273
|
+
expr_offset += sizeof(range_length);
|
|
274
|
+
|
|
275
|
+
READ_UNALIGNED(dbg, exprlen, Dwarf_Half, locptr,
|
|
276
|
+
sizeof(exprlen));
|
|
277
|
+
locptr += sizeof(exprlen);
|
|
278
|
+
expr_offset += sizeof(exprlen);
|
|
279
|
+
|
|
280
|
+
*lowpc = addr_index;
|
|
281
|
+
*highpc = range_length;
|
|
282
|
+
return_block->bl_len = exprlen;
|
|
283
|
+
return_block->bl_data = locptr;
|
|
284
|
+
return_block->bl_section_offset = expr_offset;
|
|
285
|
+
/* exprblock_size can be zero, means no expression */
|
|
286
|
+
|
|
287
|
+
expr_offset += exprlen;
|
|
288
|
+
if (expr_offset > dbg->de_debug_loc.dss_size) {
|
|
289
|
+
_dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
|
|
290
|
+
return DW_DLV_ERROR;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
break;
|
|
294
|
+
case DW_LLE_offset_pair_entry: {
|
|
295
|
+
Dwarf_ufixed startoffset = 0;
|
|
296
|
+
Dwarf_ufixed endoffset = 0;
|
|
297
|
+
Dwarf_Half exprlen = 0;
|
|
298
|
+
|
|
299
|
+
READ_UNALIGNED(dbg, startoffset, Dwarf_ufixed, locptr,
|
|
300
|
+
sizeof(startoffset));
|
|
301
|
+
locptr += sizeof(startoffset);
|
|
302
|
+
expr_offset += sizeof(startoffset);
|
|
303
|
+
|
|
304
|
+
READ_UNALIGNED(dbg, endoffset, Dwarf_ufixed, locptr,
|
|
305
|
+
sizeof(endoffset));
|
|
306
|
+
locptr += sizeof(endoffset);
|
|
307
|
+
expr_offset += sizeof(endoffset);
|
|
308
|
+
*lowpc= startoffset;
|
|
309
|
+
*highpc = endoffset;
|
|
310
|
+
|
|
311
|
+
READ_UNALIGNED(dbg, exprlen, Dwarf_Half, locptr,
|
|
312
|
+
sizeof(exprlen));
|
|
313
|
+
locptr += sizeof(exprlen);
|
|
314
|
+
expr_offset += sizeof(exprlen);
|
|
315
|
+
|
|
316
|
+
return_block->bl_len = exprlen;
|
|
317
|
+
return_block->bl_data = locptr;
|
|
318
|
+
return_block->bl_section_offset = expr_offset;
|
|
319
|
+
|
|
320
|
+
expr_offset += exprlen;
|
|
321
|
+
if (expr_offset > dbg->de_debug_loc.dss_size) {
|
|
322
|
+
_dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
|
|
323
|
+
return DW_DLV_ERROR;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
break;
|
|
327
|
+
default:
|
|
328
|
+
_dwarf_error(dbg,error,DW_DLE_LLE_CODE_UNKNOWN);
|
|
329
|
+
return DW_DLV_ERROR;
|
|
330
|
+
}
|
|
331
|
+
*lle_op = llecode;
|
|
332
|
+
return DW_DLV_OK;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
static int
|
|
337
|
+
_dwarf_get_loclist_count_dwo(Dwarf_Debug dbg,
|
|
338
|
+
Dwarf_Off loclist_offset,
|
|
339
|
+
Dwarf_Half address_size,
|
|
340
|
+
int *loclist_count, Dwarf_Error * error)
|
|
341
|
+
{
|
|
342
|
+
int count = 0;
|
|
343
|
+
Dwarf_Off offset = loclist_offset;
|
|
344
|
+
|
|
345
|
+
for (;;) {
|
|
346
|
+
Dwarf_Block_c b;
|
|
347
|
+
Dwarf_Bool at_end = FALSE;
|
|
348
|
+
Dwarf_Addr lowpc = 0;
|
|
349
|
+
Dwarf_Addr highpc = 0;
|
|
350
|
+
Dwarf_Half lle_op = 0;
|
|
351
|
+
int res = _dwarf_read_loc_section_dwo(dbg, &b,
|
|
352
|
+
&lowpc,
|
|
353
|
+
&highpc,
|
|
354
|
+
&at_end,
|
|
355
|
+
&lle_op,
|
|
356
|
+
offset,
|
|
357
|
+
address_size,
|
|
358
|
+
error);
|
|
359
|
+
if (res != DW_DLV_OK) {
|
|
360
|
+
return res;
|
|
361
|
+
}
|
|
362
|
+
if (at_end) {
|
|
363
|
+
count++;
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
offset = b.bl_len + b.bl_section_offset;
|
|
367
|
+
count++;
|
|
368
|
+
}
|
|
369
|
+
*loclist_count = count;
|
|
370
|
+
return DW_DLV_OK;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* New October 2015
|
|
374
|
+
This interface requires the use of interface functions
|
|
375
|
+
to get data from Dwarf_Locdesc_c. The structures
|
|
376
|
+
are not visible to callers. */
|
|
377
|
+
int
|
|
378
|
+
dwarf_get_loclist_c(Dwarf_Attribute attr,
|
|
379
|
+
Dwarf_Loc_Head_c * ll_header_out,
|
|
380
|
+
Dwarf_Unsigned * listlen_out,
|
|
381
|
+
Dwarf_Error * error)
|
|
382
|
+
{
|
|
383
|
+
Dwarf_Debug dbg;
|
|
384
|
+
|
|
385
|
+
/* Dwarf_Attribute that describes the DW_AT_location in die, if
|
|
386
|
+
present. */
|
|
387
|
+
Dwarf_Attribute loc_attr = attr;
|
|
388
|
+
|
|
389
|
+
/* Dwarf_Block that describes a single location expression. */
|
|
390
|
+
Dwarf_Block_c loc_block;
|
|
391
|
+
|
|
392
|
+
Dwarf_Half form = 0;
|
|
393
|
+
Dwarf_Addr lowpc = 0;
|
|
394
|
+
Dwarf_Addr highpc = 0;
|
|
395
|
+
Dwarf_Unsigned listlen = 0;
|
|
396
|
+
Dwarf_Locdesc_c llbuf = 0;
|
|
397
|
+
Dwarf_Loc_Head_c llhead = 0;
|
|
398
|
+
Dwarf_CU_Context cucontext = 0;
|
|
399
|
+
unsigned address_size = 0;
|
|
400
|
+
int cuvstamp = 0;
|
|
401
|
+
Dwarf_Bool is_cu = FALSE;
|
|
402
|
+
|
|
403
|
+
int blkres = DW_DLV_ERROR;
|
|
404
|
+
int setup_res = DW_DLV_ERROR;
|
|
405
|
+
|
|
406
|
+
/* ***** BEGIN CODE ***** */
|
|
407
|
+
setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error);
|
|
408
|
+
if (setup_res != DW_DLV_OK) {
|
|
409
|
+
return setup_res;
|
|
410
|
+
}
|
|
411
|
+
cuvstamp = cucontext->cc_version_stamp;
|
|
412
|
+
address_size = cucontext->cc_address_size;
|
|
413
|
+
/* If this is a form_block then it's a location expression. If it's
|
|
414
|
+
DW_FORM_data4 or DW_FORM_data8 in DWARF2 or DWARF3
|
|
415
|
+
(or in DWARF4 or 5 a DW_FORM_sec_offset) it's a loclist offset */
|
|
416
|
+
if (((cuvstamp == DW_CU_VERSION2 || cuvstamp == DW_CU_VERSION3) &&
|
|
417
|
+
(form == DW_FORM_data4 || form == DW_FORM_data8)) ||
|
|
418
|
+
((cuvstamp == DW_CU_VERSION4 || cuvstamp == DW_CU_VERSION5) &&
|
|
419
|
+
form == DW_FORM_sec_offset)) {
|
|
420
|
+
/* Here we have a loclist to deal with. */
|
|
421
|
+
setup_res = context_is_cu_not_tu(cucontext,&is_cu,error);
|
|
422
|
+
if(setup_res != DW_DLV_OK) {
|
|
423
|
+
return setup_res;
|
|
424
|
+
}
|
|
425
|
+
if (cucontext->cc_is_dwo) {
|
|
426
|
+
/* dwo loclist. If this were a skeleton CU
|
|
427
|
+
(ie, in the base, not dwo/dwp) then
|
|
428
|
+
it could not have a loclist. */
|
|
429
|
+
/* A reference to .debug_loc.dwo, with an offset
|
|
430
|
+
in .debug_loc.dwo of a loclist */
|
|
431
|
+
Dwarf_Unsigned loclist_offset = 0;
|
|
432
|
+
int off_res = DW_DLV_ERROR;
|
|
433
|
+
int count_res = DW_DLV_ERROR;
|
|
434
|
+
int loclist_count = 0;
|
|
435
|
+
int lli = 0;
|
|
436
|
+
|
|
437
|
+
off_res = _dwarf_get_loclist_header_start(dbg,
|
|
438
|
+
attr, &loclist_offset, error);
|
|
439
|
+
if (off_res != DW_DLV_OK) {
|
|
440
|
+
return off_res;
|
|
441
|
+
}
|
|
442
|
+
count_res = _dwarf_get_loclist_count_dwo(dbg, loclist_offset,
|
|
443
|
+
address_size, &loclist_count, error);
|
|
444
|
+
if (count_res != DW_DLV_OK) {
|
|
445
|
+
return count_res;
|
|
446
|
+
}
|
|
447
|
+
listlen = loclist_count;
|
|
448
|
+
if (loclist_count == 0) {
|
|
449
|
+
return DW_DLV_NO_ENTRY;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
llhead = (Dwarf_Loc_Head_c)_dwarf_get_alloc(dbg,
|
|
453
|
+
DW_DLA_LOC_HEAD_C, 1);
|
|
454
|
+
if (!llhead) {
|
|
455
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
456
|
+
return (DW_DLV_ERROR);
|
|
457
|
+
}
|
|
458
|
+
listlen = loclist_count;
|
|
459
|
+
llbuf = (Dwarf_Locdesc_c)
|
|
460
|
+
_dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen);
|
|
461
|
+
if (!llbuf) {
|
|
462
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
463
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
464
|
+
return (DW_DLV_ERROR);
|
|
465
|
+
}
|
|
466
|
+
llhead->ll_locdesc = llbuf;
|
|
467
|
+
llhead->ll_locdesc_count = listlen;
|
|
468
|
+
llhead->ll_from_loclist = 2;
|
|
469
|
+
llhead->ll_context = cucontext;
|
|
470
|
+
|
|
471
|
+
/* New get loc ops, DWO version */
|
|
472
|
+
for (lli = 0; lli < listlen; ++lli) {
|
|
473
|
+
int lres = 0;
|
|
474
|
+
Dwarf_Half lle_op = 0;
|
|
475
|
+
Dwarf_Bool at_end = 0;
|
|
476
|
+
|
|
477
|
+
blkres = _dwarf_read_loc_section_dwo(dbg, &loc_block,
|
|
478
|
+
&lowpc,
|
|
479
|
+
&highpc,
|
|
480
|
+
&at_end,
|
|
481
|
+
&lle_op,
|
|
482
|
+
loclist_offset,
|
|
483
|
+
address_size,
|
|
484
|
+
error);
|
|
485
|
+
if (blkres != DW_DLV_OK) {
|
|
486
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
487
|
+
return blkres;
|
|
488
|
+
}
|
|
489
|
+
/* Fills in the locdesc at index lli */
|
|
490
|
+
lres = _dwarf_get_locdesc_c(dbg,
|
|
491
|
+
lli,
|
|
492
|
+
llhead,
|
|
493
|
+
&loc_block,
|
|
494
|
+
address_size,
|
|
495
|
+
cucontext->cc_length_size,
|
|
496
|
+
cucontext->cc_version_stamp,
|
|
497
|
+
lowpc,
|
|
498
|
+
highpc,
|
|
499
|
+
error);
|
|
500
|
+
if (lres != DW_DLV_OK) {
|
|
501
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
502
|
+
/* low level error already set: let it be passed back */
|
|
503
|
+
return lres;
|
|
504
|
+
}
|
|
505
|
+
/* Override the syntesized lle value with the
|
|
506
|
+
real one. */
|
|
507
|
+
llhead->ll_locdesc[lli].ld_lle_value = lle_op;
|
|
508
|
+
|
|
509
|
+
/* Now get to next loclist entry offset. */
|
|
510
|
+
loclist_offset = loc_block.bl_section_offset +
|
|
511
|
+
loc_block.bl_len;
|
|
512
|
+
}
|
|
513
|
+
} else {
|
|
514
|
+
/* Non-dwo loclist. If this were a skeleton CU
|
|
515
|
+
(ie, in the base, not dwo/dwp) then
|
|
516
|
+
it could not have a loclist. */
|
|
517
|
+
/* A reference to .debug_loc, with an offset
|
|
518
|
+
in .debug_loc of a loclist */
|
|
519
|
+
Dwarf_Unsigned loclist_offset = 0;
|
|
520
|
+
int off_res = DW_DLV_ERROR;
|
|
521
|
+
int count_res = DW_DLV_ERROR;
|
|
522
|
+
int loclist_count = 0;
|
|
523
|
+
int lli = 0;
|
|
524
|
+
|
|
525
|
+
off_res = _dwarf_get_loclist_header_start(dbg,
|
|
526
|
+
attr, &loclist_offset, error);
|
|
527
|
+
if (off_res != DW_DLV_OK) {
|
|
528
|
+
return off_res;
|
|
529
|
+
}
|
|
530
|
+
count_res = _dwarf_get_loclist_count(dbg, loclist_offset,
|
|
531
|
+
address_size, &loclist_count, error);
|
|
532
|
+
listlen = loclist_count;
|
|
533
|
+
if (count_res != DW_DLV_OK) {
|
|
534
|
+
return count_res;
|
|
535
|
+
}
|
|
536
|
+
if (loclist_count == 0) {
|
|
537
|
+
return DW_DLV_NO_ENTRY;
|
|
538
|
+
}
|
|
539
|
+
llhead = (Dwarf_Loc_Head_c)_dwarf_get_alloc(dbg,
|
|
540
|
+
DW_DLA_LOC_HEAD_C, 1);
|
|
541
|
+
if (!llhead) {
|
|
542
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
543
|
+
return (DW_DLV_ERROR);
|
|
544
|
+
}
|
|
545
|
+
listlen = loclist_count;
|
|
546
|
+
llbuf = (Dwarf_Locdesc_c)
|
|
547
|
+
_dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen);
|
|
548
|
+
if (!llbuf) {
|
|
549
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
550
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
551
|
+
return (DW_DLV_ERROR);
|
|
552
|
+
}
|
|
553
|
+
llhead->ll_locdesc = llbuf;
|
|
554
|
+
llhead->ll_locdesc_count = listlen;
|
|
555
|
+
llhead->ll_from_loclist = 1;
|
|
556
|
+
llhead->ll_context = cucontext;
|
|
557
|
+
llhead->ll_dbg = dbg;
|
|
558
|
+
/* New locdesc and Loc, non-DWO, so old format */
|
|
559
|
+
for (lli = 0; lli < listlen; ++lli) {
|
|
560
|
+
int lres = 0;
|
|
561
|
+
Dwarf_Block_c c;
|
|
562
|
+
blkres = _dwarf_read_loc_section(dbg, &c,
|
|
563
|
+
&lowpc,
|
|
564
|
+
&highpc,
|
|
565
|
+
loclist_offset,
|
|
566
|
+
address_size,
|
|
567
|
+
error);
|
|
568
|
+
if (blkres != DW_DLV_OK) {
|
|
569
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
570
|
+
return (blkres);
|
|
571
|
+
}
|
|
572
|
+
loc_block.bl_len = c.bl_len;
|
|
573
|
+
loc_block.bl_data = c.bl_data;
|
|
574
|
+
loc_block.bl_from_loclist = c.bl_from_loclist;
|
|
575
|
+
loc_block.bl_section_offset = c.bl_section_offset;
|
|
576
|
+
loc_block.bl_locdesc_offset = loclist_offset;
|
|
577
|
+
|
|
578
|
+
/* Fills in the locdesc at index lli */
|
|
579
|
+
lres = _dwarf_get_locdesc_c(dbg,
|
|
580
|
+
lli,
|
|
581
|
+
llhead,
|
|
582
|
+
&loc_block,
|
|
583
|
+
address_size,
|
|
584
|
+
cucontext->cc_length_size,
|
|
585
|
+
cucontext->cc_version_stamp,
|
|
586
|
+
lowpc, highpc,
|
|
587
|
+
error);
|
|
588
|
+
if (lres != DW_DLV_OK) {
|
|
589
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
590
|
+
/* low level error already set:
|
|
591
|
+
let it be passed back */
|
|
592
|
+
return lres;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/* Now get to next loclist entry offset. */
|
|
596
|
+
loclist_offset = loc_block.bl_section_offset +
|
|
597
|
+
loc_block.bl_len;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
} else {
|
|
601
|
+
llhead = (Dwarf_Loc_Head_c)
|
|
602
|
+
_dwarf_get_alloc(dbg, DW_DLA_LOC_HEAD_C, 1);
|
|
603
|
+
if (!llhead) {
|
|
604
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
605
|
+
return (DW_DLV_ERROR);
|
|
606
|
+
}
|
|
607
|
+
if( form == DW_FORM_exprloc) {
|
|
608
|
+
blkres = dwarf_formexprloc(loc_attr,&loc_block.bl_len,
|
|
609
|
+
&loc_block.bl_data,error);
|
|
610
|
+
if(blkres != DW_DLV_OK) {
|
|
611
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
612
|
+
return blkres;
|
|
613
|
+
}
|
|
614
|
+
loc_block.bl_from_loclist = 0;
|
|
615
|
+
loc_block.bl_section_offset =
|
|
616
|
+
(char *)loc_block.bl_data -
|
|
617
|
+
(char *)dbg->de_debug_info.dss_data;
|
|
618
|
+
loc_block.bl_locdesc_offset = 0; /* not relevant */
|
|
619
|
+
} else {
|
|
620
|
+
Dwarf_Block *tblock = 0;
|
|
621
|
+
blkres = dwarf_formblock(loc_attr, &tblock, error);
|
|
622
|
+
if (blkres != DW_DLV_OK) {
|
|
623
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
624
|
+
return (blkres);
|
|
625
|
+
}
|
|
626
|
+
loc_block.bl_len = tblock->bl_len;
|
|
627
|
+
loc_block.bl_data = tblock->bl_data;
|
|
628
|
+
loc_block.bl_from_loclist = tblock->bl_from_loclist;
|
|
629
|
+
loc_block.bl_section_offset = tblock->bl_section_offset;
|
|
630
|
+
loc_block.bl_locdesc_offset = 0; /* not relevant */
|
|
631
|
+
/* We copied tblock contents to the stack var, so can dealloc
|
|
632
|
+
tblock now. Avoids leaks. */
|
|
633
|
+
dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
|
|
634
|
+
}
|
|
635
|
+
listlen = 1; /* One by definition of a location entry. */
|
|
636
|
+
/* This hack ensures that the Locdesc_c
|
|
637
|
+
is marked DW_LLE_start_end_entry */
|
|
638
|
+
lowpc = 0; /* HACK */
|
|
639
|
+
highpc = (Dwarf_Unsigned) (-1LL); /* HACK */
|
|
640
|
+
|
|
641
|
+
llbuf = (Dwarf_Locdesc_c)
|
|
642
|
+
_dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen);
|
|
643
|
+
if (!llbuf) {
|
|
644
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
645
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
646
|
+
return (DW_DLV_ERROR);
|
|
647
|
+
}
|
|
648
|
+
llhead->ll_locdesc = llbuf;
|
|
649
|
+
llhead->ll_locdesc = llbuf;
|
|
650
|
+
llhead->ll_locdesc_count = listlen;
|
|
651
|
+
llhead->ll_from_loclist = 0;
|
|
652
|
+
llhead->ll_context = cucontext;
|
|
653
|
+
|
|
654
|
+
/* An empty location description (block length 0) means the
|
|
655
|
+
code generator emitted no variable, the variable was not
|
|
656
|
+
generated, it was unused or perhaps never tested after being
|
|
657
|
+
set. Dwarf2, section 2.4.1 In other words, it is not an
|
|
658
|
+
error, and we don't test for block length 0 specially here. */
|
|
659
|
+
/* Fills in the locdesc at index 0 */
|
|
660
|
+
blkres = _dwarf_get_locdesc_c(dbg,
|
|
661
|
+
0, /* fake locdesc is index 0 */
|
|
662
|
+
llhead,
|
|
663
|
+
&loc_block,
|
|
664
|
+
address_size,
|
|
665
|
+
cucontext->cc_length_size,
|
|
666
|
+
cucontext->cc_version_stamp,
|
|
667
|
+
lowpc, highpc,
|
|
668
|
+
error);
|
|
669
|
+
if (blkres != DW_DLV_OK) {
|
|
670
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
671
|
+
/* low level error already set: let it be passed back */
|
|
672
|
+
return blkres;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
*ll_header_out = llhead;
|
|
676
|
+
*listlen_out = listlen;
|
|
677
|
+
return (DW_DLV_OK);
|
|
678
|
+
}
|
|
679
|
+
int
|
|
680
|
+
dwarf_loclist_from_expr_c(Dwarf_Debug dbg,
|
|
681
|
+
Dwarf_Ptr expression_in,
|
|
682
|
+
Dwarf_Unsigned expression_length,
|
|
683
|
+
Dwarf_Half address_size,
|
|
684
|
+
Dwarf_Half offset_size,
|
|
685
|
+
Dwarf_Small dwarf_version,
|
|
686
|
+
Dwarf_Loc_Head_c *loc_head,
|
|
687
|
+
Dwarf_Unsigned * listlen,
|
|
688
|
+
Dwarf_Error * error)
|
|
689
|
+
{
|
|
690
|
+
/* Dwarf_Block that describes a single location expression. */
|
|
691
|
+
Dwarf_Block_c loc_block;
|
|
692
|
+
Dwarf_Loc_Head_c llhead = 0;
|
|
693
|
+
Dwarf_Locdesc_c llbuf = 0;
|
|
694
|
+
int local_listlen = 1;
|
|
695
|
+
Dwarf_Addr lowpc = 0;
|
|
696
|
+
Dwarf_Addr highpc = MAX_ADDR;
|
|
697
|
+
Dwarf_Small version_stamp = dwarf_version;
|
|
698
|
+
int res = 0;
|
|
699
|
+
|
|
700
|
+
llhead = (Dwarf_Loc_Head_c)_dwarf_get_alloc(dbg,
|
|
701
|
+
DW_DLA_LOC_HEAD_C, 1);
|
|
702
|
+
if (!llhead) {
|
|
703
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
704
|
+
return (DW_DLV_ERROR);
|
|
705
|
+
}
|
|
706
|
+
memset(&loc_block,0,sizeof(loc_block));
|
|
707
|
+
loc_block.bl_len = expression_length;
|
|
708
|
+
loc_block.bl_data = expression_in;
|
|
709
|
+
loc_block.bl_from_loclist = 0; /* Not from loclist. */
|
|
710
|
+
loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */
|
|
711
|
+
loc_block.bl_locdesc_offset = 0; /* Fake. Not meaningful. */
|
|
712
|
+
llbuf = (Dwarf_Locdesc_c)
|
|
713
|
+
_dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, local_listlen);
|
|
714
|
+
if (!llbuf) {
|
|
715
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
716
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
717
|
+
return (DW_DLV_ERROR);
|
|
718
|
+
}
|
|
719
|
+
llhead->ll_locdesc = llbuf;
|
|
720
|
+
llhead->ll_locdesc_count = local_listlen;
|
|
721
|
+
llhead->ll_from_loclist = 0;
|
|
722
|
+
llhead->ll_context = 0; /* Not available! */
|
|
723
|
+
llhead->ll_dbg = dbg;
|
|
724
|
+
|
|
725
|
+
/* An empty location description (block length 0) means the code
|
|
726
|
+
generator emitted no variable, the variable was not generated,
|
|
727
|
+
it was unused or perhaps never tested after being set. Dwarf2,
|
|
728
|
+
section 2.4.1 In other words, it is not an error, and we don't
|
|
729
|
+
test for block length 0 specially here. */
|
|
730
|
+
|
|
731
|
+
res = _dwarf_get_locdesc_c(dbg,
|
|
732
|
+
0,
|
|
733
|
+
llhead,
|
|
734
|
+
&loc_block,
|
|
735
|
+
address_size,
|
|
736
|
+
offset_size,
|
|
737
|
+
version_stamp,
|
|
738
|
+
lowpc,
|
|
739
|
+
highpc,
|
|
740
|
+
error);
|
|
741
|
+
if (res != DW_DLV_OK) {
|
|
742
|
+
/* low level error already set: let it be passed back */
|
|
743
|
+
dwarf_loc_head_c_dealloc(llhead);
|
|
744
|
+
return (DW_DLV_ERROR);
|
|
745
|
+
}
|
|
746
|
+
*loc_head = llhead;
|
|
747
|
+
*listlen = local_listlen;
|
|
748
|
+
return (DW_DLV_OK);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
int
|
|
752
|
+
dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c loclist_head,
|
|
753
|
+
Dwarf_Unsigned index,
|
|
754
|
+
Dwarf_Small * lle_value_out, /* identifies type of loclist entry*/
|
|
755
|
+
Dwarf_Addr * lowpc_out,
|
|
756
|
+
Dwarf_Addr * hipc_out,
|
|
757
|
+
Dwarf_Unsigned * loclist_count_out,
|
|
758
|
+
|
|
759
|
+
/* Returns pointer to the specific locdesc of the index; */
|
|
760
|
+
Dwarf_Locdesc_c* locdesc_entry_out,
|
|
761
|
+
Dwarf_Small * loclist_source_out, /* 0,1, or 2 */
|
|
762
|
+
Dwarf_Unsigned * expression_offset_out,
|
|
763
|
+
Dwarf_Unsigned * locdesc_offset_out,
|
|
764
|
+
Dwarf_Error * error)
|
|
765
|
+
{
|
|
766
|
+
Dwarf_Locdesc_c descs_base = 0;
|
|
767
|
+
Dwarf_Locdesc_c desc = 0;
|
|
768
|
+
Dwarf_Unsigned desc_count = 0;
|
|
769
|
+
Dwarf_Debug dbg;
|
|
770
|
+
|
|
771
|
+
desc_count = loclist_head->ll_locdesc_count;
|
|
772
|
+
descs_base = loclist_head->ll_locdesc;
|
|
773
|
+
dbg = loclist_head->ll_dbg;
|
|
774
|
+
if (index >= desc_count) {
|
|
775
|
+
_dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR);
|
|
776
|
+
return (DW_DLV_ERROR);
|
|
777
|
+
}
|
|
778
|
+
desc = descs_base + index;
|
|
779
|
+
*lle_value_out = desc->ld_lle_value;
|
|
780
|
+
*lowpc_out = desc->ld_lopc;
|
|
781
|
+
*hipc_out = desc->ld_hipc;
|
|
782
|
+
*loclist_count_out = desc->ld_cents;
|
|
783
|
+
*locdesc_entry_out = desc;
|
|
784
|
+
*loclist_source_out = desc->ld_from_loclist;
|
|
785
|
+
*expression_offset_out = desc->ld_section_offset;
|
|
786
|
+
*locdesc_offset_out = desc->ld_locdesc_offset;
|
|
787
|
+
return DW_DLV_OK;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
int
|
|
791
|
+
dwarf_get_location_op_value_c(Dwarf_Locdesc_c locdesc,
|
|
792
|
+
Dwarf_Unsigned index,
|
|
793
|
+
Dwarf_Small * atom_out,
|
|
794
|
+
Dwarf_Unsigned * operand1,
|
|
795
|
+
Dwarf_Unsigned * operand2,
|
|
796
|
+
Dwarf_Unsigned * operand3,
|
|
797
|
+
Dwarf_Unsigned * offset_for_branch,
|
|
798
|
+
Dwarf_Error* error)
|
|
799
|
+
{
|
|
800
|
+
Dwarf_Loc_c op = 0;
|
|
801
|
+
Dwarf_Unsigned max = locdesc->ld_cents;
|
|
802
|
+
|
|
803
|
+
if(index >= max) {
|
|
804
|
+
Dwarf_Debug dbg = locdesc->ld_loclist_head->ll_dbg;
|
|
805
|
+
_dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR);
|
|
806
|
+
return (DW_DLV_ERROR);
|
|
807
|
+
}
|
|
808
|
+
op = locdesc->ld_s + index;
|
|
809
|
+
*atom_out = op->lr_atom;
|
|
810
|
+
*operand1 = op->lr_number;
|
|
811
|
+
*operand2 = op->lr_number2;
|
|
812
|
+
*operand3 = op->lr_number3;
|
|
813
|
+
*offset_for_branch = op->lr_offset;
|
|
814
|
+
return DW_DLV_OK;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
void
|
|
820
|
+
dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head)
|
|
821
|
+
{
|
|
822
|
+
Dwarf_Debug dbg = loclist_head->ll_dbg;
|
|
823
|
+
Dwarf_Locdesc_c desc = loclist_head->ll_locdesc;
|
|
824
|
+
if( desc) {
|
|
825
|
+
Dwarf_Loc_c loc = desc->ld_s;
|
|
826
|
+
if(loc) {
|
|
827
|
+
dwarf_dealloc(dbg,loc,DW_DLA_LOC_BLOCK_C);
|
|
828
|
+
}
|
|
829
|
+
dwarf_dealloc(dbg,desc,DW_DLA_LOCDESC_C);
|
|
830
|
+
}
|
|
831
|
+
dwarf_dealloc(dbg,loclist_head,DW_DLA_LOC_HEAD_C);
|
|
832
|
+
}
|
|
833
|
+
|