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,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
|
+
|