rdwarf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +28 -0
  6. data/README.md +39 -0
  7. data/Rakefile +8 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +7 -0
  10. data/ext/rdwarf/depend +5 -0
  11. data/ext/rdwarf/extconf.rb +29 -0
  12. data/ext/rdwarf/libdwarf/CHANGES +102 -0
  13. data/ext/rdwarf/libdwarf/CODINGSTYLE +71 -0
  14. data/ext/rdwarf/libdwarf/COPYING +28 -0
  15. data/ext/rdwarf/libdwarf/ChangeLog +619 -0
  16. data/ext/rdwarf/libdwarf/ChangeLog2006 +835 -0
  17. data/ext/rdwarf/libdwarf/ChangeLog2007 +217 -0
  18. data/ext/rdwarf/libdwarf/ChangeLog2008 +263 -0
  19. data/ext/rdwarf/libdwarf/ChangeLog2009 +348 -0
  20. data/ext/rdwarf/libdwarf/ChangeLog2010 +175 -0
  21. data/ext/rdwarf/libdwarf/ChangeLog2011 +297 -0
  22. data/ext/rdwarf/libdwarf/ChangeLog2012 +131 -0
  23. data/ext/rdwarf/libdwarf/ChangeLog2013 +238 -0
  24. data/ext/rdwarf/libdwarf/ChangeLog2014 +399 -0
  25. data/ext/rdwarf/libdwarf/LGPL.txt +504 -0
  26. data/ext/rdwarf/libdwarf/LIBDWARFCOPYRIGHT +40 -0
  27. data/ext/rdwarf/libdwarf/Makefile.in +220 -0
  28. data/ext/rdwarf/libdwarf/NEWS +535 -0
  29. data/ext/rdwarf/libdwarf/README +235 -0
  30. data/ext/rdwarf/libdwarf/checkexamples.c +1179 -0
  31. data/ext/rdwarf/libdwarf/cmplrs/dwarf_addr_finder.h +55 -0
  32. data/ext/rdwarf/libdwarf/common.c +62 -0
  33. data/ext/rdwarf/libdwarf/common.h +38 -0
  34. data/ext/rdwarf/libdwarf/config.h.in +146 -0
  35. data/ext/rdwarf/libdwarf/configure +5581 -0
  36. data/ext/rdwarf/libdwarf/configure.in +167 -0
  37. data/ext/rdwarf/libdwarf/dw-linetableheader.txt +39 -0
  38. data/ext/rdwarf/libdwarf/dwarf.h +1342 -0
  39. data/ext/rdwarf/libdwarf/dwarf_abbrev.c +291 -0
  40. data/ext/rdwarf/libdwarf/dwarf_abbrev.h +45 -0
  41. data/ext/rdwarf/libdwarf/dwarf_addr_finder.c +676 -0
  42. data/ext/rdwarf/libdwarf/dwarf_alloc.c +685 -0
  43. data/ext/rdwarf/libdwarf/dwarf_alloc.h +38 -0
  44. data/ext/rdwarf/libdwarf/dwarf_arange.c +595 -0
  45. data/ext/rdwarf/libdwarf/dwarf_arange.h +62 -0
  46. data/ext/rdwarf/libdwarf/dwarf_base_types.h +157 -0
  47. data/ext/rdwarf/libdwarf/dwarf_die_deliv.c +1802 -0
  48. data/ext/rdwarf/libdwarf/dwarf_die_deliv.h +46 -0
  49. data/ext/rdwarf/libdwarf/dwarf_elf_access.c +1348 -0
  50. data/ext/rdwarf/libdwarf/dwarf_elf_access.h +46 -0
  51. data/ext/rdwarf/libdwarf/dwarf_error.c +492 -0
  52. data/ext/rdwarf/libdwarf/dwarf_error.h +53 -0
  53. data/ext/rdwarf/libdwarf/dwarf_form.c +1302 -0
  54. data/ext/rdwarf/libdwarf/dwarf_frame.c +2454 -0
  55. data/ext/rdwarf/libdwarf/dwarf_frame.h +418 -0
  56. data/ext/rdwarf/libdwarf/dwarf_frame2.c +1533 -0
  57. data/ext/rdwarf/libdwarf/dwarf_frame3.c +282 -0
  58. data/ext/rdwarf/libdwarf/dwarf_funcs.c +123 -0
  59. data/ext/rdwarf/libdwarf/dwarf_funcs.h +33 -0
  60. data/ext/rdwarf/libdwarf/dwarf_gdbindex.c +520 -0
  61. data/ext/rdwarf/libdwarf/dwarf_gdbindex.h +97 -0
  62. data/ext/rdwarf/libdwarf/dwarf_global.c +612 -0
  63. data/ext/rdwarf/libdwarf/dwarf_global.h +117 -0
  64. data/ext/rdwarf/libdwarf/dwarf_harmless.c +228 -0
  65. data/ext/rdwarf/libdwarf/dwarf_harmless.h +31 -0
  66. data/ext/rdwarf/libdwarf/dwarf_incl.h +61 -0
  67. data/ext/rdwarf/libdwarf/dwarf_init_finish.c +1263 -0
  68. data/ext/rdwarf/libdwarf/dwarf_leb.c +159 -0
  69. data/ext/rdwarf/libdwarf/dwarf_line.c +1822 -0
  70. data/ext/rdwarf/libdwarf/dwarf_line.h +446 -0
  71. data/ext/rdwarf/libdwarf/dwarf_line2.c +98 -0
  72. data/ext/rdwarf/libdwarf/dwarf_line_table_reader_common.c +1583 -0
  73. data/ext/rdwarf/libdwarf/dwarf_loc.c +1525 -0
  74. data/ext/rdwarf/libdwarf/dwarf_loc.h +149 -0
  75. data/ext/rdwarf/libdwarf/dwarf_loc2.c +833 -0
  76. data/ext/rdwarf/libdwarf/dwarf_macro.c +479 -0
  77. data/ext/rdwarf/libdwarf/dwarf_macro.h +35 -0
  78. data/ext/rdwarf/libdwarf/dwarf_opaque.h +778 -0
  79. data/ext/rdwarf/libdwarf/dwarf_original_elf_init.c +219 -0
  80. data/ext/rdwarf/libdwarf/dwarf_print_lines.c +631 -0
  81. data/ext/rdwarf/libdwarf/dwarf_pubtypes.c +132 -0
  82. data/ext/rdwarf/libdwarf/dwarf_query.c +1594 -0
  83. data/ext/rdwarf/libdwarf/dwarf_ranges.c +194 -0
  84. data/ext/rdwarf/libdwarf/dwarf_reloc_arm.h +308 -0
  85. data/ext/rdwarf/libdwarf/dwarf_reloc_mips.h +117 -0
  86. data/ext/rdwarf/libdwarf/dwarf_reloc_ppc.h +242 -0
  87. data/ext/rdwarf/libdwarf/dwarf_reloc_ppc64.h +272 -0
  88. data/ext/rdwarf/libdwarf/dwarf_reloc_x86_64.h +127 -0
  89. data/ext/rdwarf/libdwarf/dwarf_sort_line.c +665 -0
  90. data/ext/rdwarf/libdwarf/dwarf_string.c +82 -0
  91. data/ext/rdwarf/libdwarf/dwarf_stubs.c +38 -0
  92. data/ext/rdwarf/libdwarf/dwarf_tied.c +423 -0
  93. data/ext/rdwarf/libdwarf/dwarf_tsearch.h +125 -0
  94. data/ext/rdwarf/libdwarf/dwarf_tsearchhash.c +675 -0
  95. data/ext/rdwarf/libdwarf/dwarf_types.c +121 -0
  96. data/ext/rdwarf/libdwarf/dwarf_types.h +32 -0
  97. data/ext/rdwarf/libdwarf/dwarf_util.c +913 -0
  98. data/ext/rdwarf/libdwarf/dwarf_util.h +324 -0
  99. data/ext/rdwarf/libdwarf/dwarf_vars.c +125 -0
  100. data/ext/rdwarf/libdwarf/dwarf_vars.h +29 -0
  101. data/ext/rdwarf/libdwarf/dwarf_weaks.c +123 -0
  102. data/ext/rdwarf/libdwarf/dwarf_weaks.h +29 -0
  103. data/ext/rdwarf/libdwarf/dwarf_xu_index.c +579 -0
  104. data/ext/rdwarf/libdwarf/dwarf_xu_index.h +68 -0
  105. data/ext/rdwarf/libdwarf/dwgetopt.c +181 -0
  106. data/ext/rdwarf/libdwarf/dwgetopt.h +51 -0
  107. data/ext/rdwarf/libdwarf/gennames.c +531 -0
  108. data/ext/rdwarf/libdwarf/install.sh +119 -0
  109. data/ext/rdwarf/libdwarf/libdwarf.h.in +3746 -0
  110. data/ext/rdwarf/libdwarf/libdwarf2.1.mm +9805 -0
  111. data/ext/rdwarf/libdwarf/libdwarf2.1.pdf +0 -0
  112. data/ext/rdwarf/libdwarf/libdwarf2p.1.mm +2807 -0
  113. data/ext/rdwarf/libdwarf/libdwarf2p.1.pdf +0 -0
  114. data/ext/rdwarf/libdwarf/libdwarfdefs.h +81 -0
  115. data/ext/rdwarf/libdwarf/malloc_check.c +327 -0
  116. data/ext/rdwarf/libdwarf/malloc_check.h +52 -0
  117. data/ext/rdwarf/libdwarf/mips_extensions.mm +1266 -0
  118. data/ext/rdwarf/libdwarf/mips_extensions.pdf +0 -0
  119. data/ext/rdwarf/libdwarf/pro_alloc.c +179 -0
  120. data/ext/rdwarf/libdwarf/pro_alloc.h +33 -0
  121. data/ext/rdwarf/libdwarf/pro_arange.c +310 -0
  122. data/ext/rdwarf/libdwarf/pro_arange.h +51 -0
  123. data/ext/rdwarf/libdwarf/pro_die.c +431 -0
  124. data/ext/rdwarf/libdwarf/pro_die.h +59 -0
  125. data/ext/rdwarf/libdwarf/pro_encode_nm.c +108 -0
  126. data/ext/rdwarf/libdwarf/pro_encode_nm.h +39 -0
  127. data/ext/rdwarf/libdwarf/pro_error.c +96 -0
  128. data/ext/rdwarf/libdwarf/pro_error.h +43 -0
  129. data/ext/rdwarf/libdwarf/pro_expr.c +575 -0
  130. data/ext/rdwarf/libdwarf/pro_expr.h +36 -0
  131. data/ext/rdwarf/libdwarf/pro_finish.c +45 -0
  132. data/ext/rdwarf/libdwarf/pro_forms.c +1271 -0
  133. data/ext/rdwarf/libdwarf/pro_frame.c +572 -0
  134. data/ext/rdwarf/libdwarf/pro_frame.h +120 -0
  135. data/ext/rdwarf/libdwarf/pro_funcs.c +50 -0
  136. data/ext/rdwarf/libdwarf/pro_incl.h +91 -0
  137. data/ext/rdwarf/libdwarf/pro_init.c +327 -0
  138. data/ext/rdwarf/libdwarf/pro_line.c +373 -0
  139. data/ext/rdwarf/libdwarf/pro_line.h +112 -0
  140. data/ext/rdwarf/libdwarf/pro_macinfo.c +457 -0
  141. data/ext/rdwarf/libdwarf/pro_macinfo.h +31 -0
  142. data/ext/rdwarf/libdwarf/pro_opaque.h +513 -0
  143. data/ext/rdwarf/libdwarf/pro_pubnames.c +60 -0
  144. data/ext/rdwarf/libdwarf/pro_reloc.c +253 -0
  145. data/ext/rdwarf/libdwarf/pro_reloc.h +38 -0
  146. data/ext/rdwarf/libdwarf/pro_reloc_stream.c +256 -0
  147. data/ext/rdwarf/libdwarf/pro_reloc_stream.h +52 -0
  148. data/ext/rdwarf/libdwarf/pro_reloc_symbolic.c +245 -0
  149. data/ext/rdwarf/libdwarf/pro_reloc_symbolic.h +45 -0
  150. data/ext/rdwarf/libdwarf/pro_section.c +2233 -0
  151. data/ext/rdwarf/libdwarf/pro_section.h +100 -0
  152. data/ext/rdwarf/libdwarf/pro_types.c +274 -0
  153. data/ext/rdwarf/libdwarf/pro_types.h +34 -0
  154. data/ext/rdwarf/libdwarf/pro_util.h +38 -0
  155. data/ext/rdwarf/libdwarf/pro_vars.c +52 -0
  156. data/ext/rdwarf/libdwarf/pro_weaks.c +51 -0
  157. data/ext/rdwarf/rdwarf.c +765 -0
  158. data/ext/rdwarf/rdwarf.h +52 -0
  159. data/ext/rdwarf/rdwarf_names_gen.rb +109 -0
  160. data/lib/rdwarf.rb +181 -0
  161. data/lib/rdwarf/version.rb +3 -0
  162. data/rdwarf.gemspec +30 -0
  163. metadata +251 -0
@@ -0,0 +1,132 @@
1
+ /*
2
+
3
+ Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
4
+ Portions Copyright (C) 2009-2010 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
+ /* Reads DWARF3 .debug_pubtypes section. */
29
+
30
+ #include "config.h"
31
+ #include "dwarf_incl.h"
32
+ #include <stdio.h>
33
+ #include "dwarf_types.h"
34
+ #include "dwarf_global.h"
35
+
36
+ int
37
+ dwarf_get_pubtypes(Dwarf_Debug dbg,
38
+ Dwarf_Type ** types,
39
+ Dwarf_Signed * ret_type_count, Dwarf_Error * error)
40
+ {
41
+ int res = _dwarf_load_section(dbg, &dbg->de_debug_pubtypes,error);
42
+ if (res != DW_DLV_OK) {
43
+ return res;
44
+ }
45
+ if (!dbg->de_debug_pubtypes.dss_size) {
46
+ return (DW_DLV_NO_ENTRY);
47
+ }
48
+
49
+
50
+ return _dwarf_internal_get_pubnames_like_data(dbg,
51
+ dbg->de_debug_pubtypes.dss_data,
52
+ dbg->de_debug_pubtypes.dss_size,
53
+ (Dwarf_Global **) types, /* Type punning for sections
54
+ with identical format. */
55
+ ret_type_count, error,
56
+ DW_DLA_PUBTYPES_CONTEXT,
57
+ DW_DLA_GLOBAL, /* We don't have DW_DLA_PUBTYPES,
58
+ so use DW_DLA_GLOBAL. */
59
+ DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD,
60
+ DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR);
61
+ }
62
+
63
+ /* Deallocating fully requires deallocating the list
64
+ and all entries. But some internal data is
65
+ not exposed, so we need a function with internal knowledge.
66
+ */
67
+
68
+ void
69
+ dwarf_pubtypes_dealloc(Dwarf_Debug dbg, Dwarf_Type * dwgl,
70
+ Dwarf_Signed count)
71
+ {
72
+ _dwarf_internal_globals_dealloc(dbg,
73
+ (Dwarf_Global *) dwgl,
74
+ count,
75
+ DW_DLA_PUBTYPES_CONTEXT,
76
+ DW_DLA_GLOBAL, /* We don't have DW_DLA_PUBTYPES,
77
+ so use DW_DLA_GLOBAL. */
78
+ DW_DLA_LIST);
79
+ return;
80
+ }
81
+
82
+
83
+
84
+ int
85
+ dwarf_pubtypename(Dwarf_Type type_in, char **ret_name,
86
+ Dwarf_Error * error)
87
+ {
88
+ Dwarf_Global type = (Dwarf_Global) type_in;
89
+ if (type == NULL) {
90
+ _dwarf_error(NULL, error, DW_DLE_TYPE_NULL);
91
+ return (DW_DLV_ERROR);
92
+ }
93
+ *ret_name = (char *) (type->gl_name);
94
+ return DW_DLV_OK;
95
+ }
96
+
97
+
98
+ int
99
+ dwarf_pubtype_type_die_offset(Dwarf_Type type_in,
100
+ Dwarf_Off * ret_offset,
101
+ Dwarf_Error * error)
102
+ {
103
+ Dwarf_Global type = (Dwarf_Global) type_in;
104
+
105
+ return dwarf_global_die_offset(type, ret_offset, error);
106
+ }
107
+
108
+
109
+ int
110
+ dwarf_pubtype_cu_offset(Dwarf_Type type_in,
111
+ Dwarf_Off * ret_offset, Dwarf_Error * error)
112
+ {
113
+ Dwarf_Global type = (Dwarf_Global) type_in;
114
+
115
+ return dwarf_global_cu_offset(type, ret_offset, error);
116
+
117
+ }
118
+
119
+
120
+ int
121
+ dwarf_pubtype_name_offsets(Dwarf_Type type_in,
122
+ char **returned_name,
123
+ Dwarf_Off * die_offset,
124
+ Dwarf_Off * cu_die_offset,
125
+ Dwarf_Error * error)
126
+ {
127
+ Dwarf_Global type = (Dwarf_Global) type_in;
128
+
129
+ return dwarf_global_name_offsets(type,
130
+ returned_name,
131
+ die_offset, cu_die_offset, error);
132
+ }
@@ -0,0 +1,1594 @@
1
+ /*
2
+
3
+ Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved.
4
+ Portions Copyright (C) 2007-2013 David Anderson. All Rights Reserved.
5
+ Portions Copyright 2012 SN Systems Ltd. All rights reserved.
6
+
7
+ This program is free software; you can redistribute it and/or modify it
8
+ under the terms of version 2.1 of the GNU Lesser General Public License
9
+ as published by the Free Software Foundation.
10
+
11
+ This program is distributed in the hope that it would be useful, but
12
+ WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+
15
+ Further, this software is distributed without any warranty that it is
16
+ free of the rightful claim of any third person regarding infringement
17
+ or the like. Any license provided herein, whether implied or
18
+ otherwise, applies only to this software file. Patent licenses, if
19
+ any, provided herein do not apply to combinations of this program with
20
+ other software, or any other product whatsoever.
21
+
22
+ You should have received a copy of the GNU Lesser General Public
23
+ License along with this program; if not, write the Free Software
24
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25
+ USA.
26
+
27
+ */
28
+
29
+ #include "config.h"
30
+ #include "dwarf_incl.h"
31
+ #include <stdio.h>
32
+ #include "dwarf_die_deliv.h"
33
+
34
+ #define TRUE 1
35
+ static int _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
36
+ Dwarf_Half attr,
37
+ Dwarf_Unsigned * return_val,
38
+ Dwarf_Error * error);
39
+
40
+ static int _dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg,
41
+ Dwarf_CU_Context context,
42
+ Dwarf_Unsigned * rabase_out,
43
+ Dwarf_Error * error);
44
+
45
+ static int _dwarf_get_address_base_attr_value(Dwarf_Debug dbg,
46
+ Dwarf_CU_Context context,
47
+ Dwarf_Unsigned *abase_out,
48
+ Dwarf_Error *error);
49
+
50
+ int dwarf_get_offset_size(Dwarf_Debug dbg,
51
+ Dwarf_Half * offset_size,
52
+ Dwarf_Error * error)
53
+ {
54
+ if (dbg == 0) {
55
+ _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
56
+ return (DW_DLV_ERROR);
57
+ }
58
+ *offset_size = dbg->de_length_size;;
59
+ return DW_DLV_OK;
60
+ }
61
+
62
+
63
+ /* This is normally reliable.
64
+ But not always.
65
+ If different compilation
66
+ units have different address sizes
67
+ this may not give the correct value in all contexts.
68
+ If the Elf offset size != address_size
69
+ (for example if address_size = 4 but recorded in elf64 object)
70
+ this may not give the correct value in all contexts.
71
+ */
72
+ int
73
+ dwarf_get_address_size(Dwarf_Debug dbg,
74
+ Dwarf_Half * ret_addr_size, Dwarf_Error * error)
75
+ {
76
+ Dwarf_Half address_size = 0;
77
+
78
+ if (dbg == 0) {
79
+ _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
80
+ return (DW_DLV_ERROR);
81
+ }
82
+ address_size = dbg->de_pointer_size;
83
+ *ret_addr_size = address_size;
84
+ return DW_DLV_OK;
85
+ }
86
+
87
+ /* This will be correct in all contexts where the
88
+ CU context of a DIE is known.
89
+ */
90
+ int
91
+ dwarf_get_die_address_size(Dwarf_Die die,
92
+ Dwarf_Half * ret_addr_size, Dwarf_Error * error)
93
+ {
94
+ Dwarf_Half address_size = 0;
95
+ CHECK_DIE(die, DW_DLV_ERROR);
96
+ address_size = die->di_cu_context->cc_address_size;
97
+ *ret_addr_size = address_size;
98
+ return DW_DLV_OK;
99
+ }
100
+
101
+ int
102
+ dwarf_dieoffset(Dwarf_Die die,
103
+ Dwarf_Off * ret_offset, Dwarf_Error * error)
104
+ {
105
+ Dwarf_Small *dataptr = 0;
106
+ Dwarf_Debug dbg = 0;
107
+
108
+ CHECK_DIE(die, DW_DLV_ERROR);
109
+ dbg = die->di_cu_context->cc_dbg;
110
+ dataptr = die->di_is_info? dbg->de_debug_info.dss_data:
111
+ dbg->de_debug_types.dss_data;
112
+
113
+ *ret_offset = (die->di_debug_ptr - dataptr);
114
+ return DW_DLV_OK;
115
+ }
116
+
117
+
118
+ /* This function returns the offset of
119
+ the die relative to the start of its
120
+ compilation-unit rather than .debug_info.
121
+ Returns DW_DLV_ERROR on error. */
122
+ int
123
+ dwarf_die_CU_offset(Dwarf_Die die,
124
+ Dwarf_Off * cu_off, Dwarf_Error * error)
125
+ {
126
+ Dwarf_CU_Context cu_context = 0;
127
+ Dwarf_Small *dataptr = 0;
128
+ Dwarf_Debug dbg = 0;
129
+
130
+ CHECK_DIE(die, DW_DLV_ERROR);
131
+ cu_context = die->di_cu_context;
132
+ dbg = die->di_cu_context->cc_dbg;
133
+ dataptr = die->di_is_info? dbg->de_debug_info.dss_data:
134
+ dbg->de_debug_types.dss_data;
135
+
136
+ *cu_off = (die->di_debug_ptr - dataptr - cu_context->cc_debug_offset);
137
+ return DW_DLV_OK;
138
+ }
139
+
140
+ /* A common function to get both offsets (local and global) */
141
+ int
142
+ dwarf_die_offsets(Dwarf_Die die,
143
+ Dwarf_Off *off,
144
+ Dwarf_Off *cu_off,
145
+ Dwarf_Error *error)
146
+ {
147
+ *off = 0;
148
+ *cu_off = 0;
149
+ if (DW_DLV_OK == dwarf_dieoffset(die,off,error) &&
150
+ DW_DLV_OK == dwarf_die_CU_offset(die,cu_off,error)) {
151
+ return DW_DLV_OK;
152
+ }
153
+ return DW_DLV_ERROR;
154
+ }
155
+
156
+ /* This function returns the global offset
157
+ (meaning the section offset) and length of
158
+ the CU that this die is a part of.
159
+ Used for correctness checking by dwarfdump. */
160
+ int
161
+ dwarf_die_CU_offset_range(Dwarf_Die die,
162
+ Dwarf_Off * cu_off,
163
+ Dwarf_Off * cu_length,
164
+ Dwarf_Error * error)
165
+ {
166
+ Dwarf_CU_Context cu_context = 0;
167
+
168
+ CHECK_DIE(die, DW_DLV_ERROR);
169
+ cu_context = die->di_cu_context;
170
+
171
+ *cu_off = cu_context->cc_debug_offset;
172
+ *cu_length = cu_context->cc_length + cu_context->cc_length_size
173
+ + cu_context->cc_extension_size;
174
+ return DW_DLV_OK;
175
+ }
176
+
177
+
178
+
179
+ int
180
+ dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error)
181
+ {
182
+ CHECK_DIE(die, DW_DLV_ERROR);
183
+ *tag = (die->di_abbrev_list->ab_tag);
184
+ return DW_DLV_OK;
185
+ }
186
+
187
+ /* If the input is improper (see DW_DLV_ERROR)
188
+ this may leak memory. Such badly formed input
189
+ should be very very rare.
190
+ */
191
+ int
192
+ dwarf_attrlist(Dwarf_Die die,
193
+ Dwarf_Attribute ** attrbuf,
194
+ Dwarf_Signed * attrcnt, Dwarf_Error * error)
195
+ {
196
+ Dwarf_Word attr_count = 0;
197
+ Dwarf_Word i = 0;
198
+ Dwarf_Half attr = 0;
199
+ Dwarf_Half attr_form = 0;
200
+ Dwarf_Byte_Ptr abbrev_ptr = 0;
201
+ Dwarf_Abbrev_List abbrev_list = 0;
202
+ Dwarf_Attribute new_attr = 0;
203
+ Dwarf_Attribute head_attr = NULL;
204
+ Dwarf_Attribute curr_attr = NULL;
205
+ Dwarf_Attribute *attr_ptr = 0;
206
+ Dwarf_Debug dbg = 0;
207
+ Dwarf_Byte_Ptr info_ptr = 0;
208
+
209
+ CHECK_DIE(die, DW_DLV_ERROR);
210
+ dbg = die->di_cu_context->cc_dbg;
211
+
212
+ abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
213
+ die->di_abbrev_list->ab_code);
214
+ if (abbrev_list == NULL) {
215
+ _dwarf_error(dbg,error,DW_DLE_CU_DIE_NO_ABBREV_LIST);
216
+ return (DW_DLV_ERROR);
217
+ }
218
+ abbrev_ptr = abbrev_list->ab_abbrev_ptr;
219
+
220
+ info_ptr = die->di_debug_ptr;
221
+ SKIP_LEB128_WORD(info_ptr);
222
+
223
+ do {
224
+ Dwarf_Unsigned utmp2;
225
+
226
+ DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
227
+ attr = (Dwarf_Half) utmp2;
228
+ DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
229
+ attr_form = (Dwarf_Half) utmp2;
230
+
231
+ if (attr != 0) {
232
+ new_attr =
233
+ (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
234
+ if (new_attr == NULL) {
235
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
236
+ return (DW_DLV_ERROR);
237
+ }
238
+
239
+ new_attr->ar_attribute = attr;
240
+ new_attr->ar_attribute_form_direct = attr_form;
241
+ new_attr->ar_attribute_form = attr_form;
242
+ if (attr_form == DW_FORM_indirect) {
243
+ Dwarf_Unsigned utmp6;
244
+
245
+ /* DECODE_LEB128_UWORD does info_ptr update */
246
+ DECODE_LEB128_UWORD(info_ptr, utmp6);
247
+ attr_form = (Dwarf_Half) utmp6;
248
+ new_attr->ar_attribute_form = attr_form;
249
+ }
250
+ if (_dwarf_reference_outside_section(die,
251
+ (Dwarf_Small*) info_ptr,
252
+ (Dwarf_Small*) info_ptr)) {
253
+ _dwarf_error(dbg, error,DW_DLE_ATTR_OUTSIDE_SECTION);
254
+ return DW_DLV_ERROR;
255
+ }
256
+ new_attr->ar_cu_context = die->di_cu_context;
257
+ new_attr->ar_debug_ptr = info_ptr;
258
+ new_attr->ar_die = die;
259
+ {
260
+ Dwarf_Unsigned sov = 0;
261
+ int res = _dwarf_get_size_of_val(dbg,
262
+ attr_form,
263
+ die->di_cu_context->cc_version_stamp,
264
+ die->di_cu_context->cc_address_size,
265
+ info_ptr,
266
+ die->di_cu_context->cc_length_size,
267
+ &sov,
268
+ error);
269
+ if(res!= DW_DLV_OK) {
270
+ return res;
271
+ }
272
+ info_ptr += sov;
273
+ }
274
+
275
+ if (head_attr == NULL)
276
+ head_attr = curr_attr = new_attr;
277
+ else {
278
+ curr_attr->ar_next = new_attr;
279
+ curr_attr = new_attr;
280
+ }
281
+ attr_count++;
282
+ }
283
+ } while (attr != 0 || attr_form != 0);
284
+
285
+ if (attr_count == 0) {
286
+ *attrbuf = NULL;
287
+ *attrcnt = 0;
288
+ return (DW_DLV_NO_ENTRY);
289
+ }
290
+
291
+ attr_ptr = (Dwarf_Attribute *)
292
+ _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
293
+ if (attr_ptr == NULL) {
294
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
295
+ return (DW_DLV_ERROR);
296
+ }
297
+
298
+ curr_attr = head_attr;
299
+ for (i = 0; i < attr_count; i++) {
300
+ *(attr_ptr + i) = curr_attr;
301
+ curr_attr = curr_attr->ar_next;
302
+ }
303
+
304
+ *attrbuf = attr_ptr;
305
+ *attrcnt = attr_count;
306
+ return (DW_DLV_OK);
307
+ }
308
+
309
+
310
+ /*
311
+ This function takes a die, and an attr, and returns
312
+ a pointer to the start of the value of that attr in
313
+ the given die in the .debug_info section. The form
314
+ is returned in *attr_form.
315
+
316
+ Returns NULL on error, or if attr is not found.
317
+ However, *attr_form is 0 on error, and positive
318
+ otherwise.
319
+ */
320
+ static int
321
+ _dwarf_get_value_ptr(Dwarf_Die die,
322
+ Dwarf_Half attr,
323
+ Dwarf_Half * attr_form,
324
+ Dwarf_Byte_Ptr * ptr_to_value,
325
+ Dwarf_Error *error)
326
+ {
327
+ Dwarf_Byte_Ptr abbrev_ptr = 0;
328
+ Dwarf_Abbrev_List abbrev_list;
329
+ Dwarf_Half curr_attr = 0;
330
+ Dwarf_Half curr_attr_form = 0;
331
+ Dwarf_Byte_Ptr info_ptr = 0;
332
+ Dwarf_CU_Context context = die->di_cu_context;
333
+ Dwarf_Byte_Ptr die_info_end = 0;
334
+ Dwarf_Debug dbg = 0;
335
+
336
+ if (!context) {
337
+ _dwarf_error(NULL,error,DW_DLE_DIE_NO_CU_CONTEXT);
338
+ return DW_DLV_ERROR;
339
+ }
340
+ dbg = context->cc_dbg;
341
+ die_info_end = _dwarf_calculate_section_end_ptr(context);
342
+ abbrev_list = _dwarf_get_abbrev_for_code(context,
343
+ die->di_abbrev_list->ab_code);
344
+ if (abbrev_list == NULL) {
345
+ /* Should this be DW_DLV_NO_ENTRY? */
346
+ _dwarf_error(dbg,error,DW_DLE_CU_DIE_NO_ABBREV_LIST);
347
+ return DW_DLV_ERROR;
348
+ }
349
+ abbrev_ptr = abbrev_list->ab_abbrev_ptr;
350
+
351
+ info_ptr = die->di_debug_ptr;
352
+ SKIP_LEB128_WORD(info_ptr);
353
+
354
+ do {
355
+ Dwarf_Unsigned utmp3 = 0;
356
+ Dwarf_Unsigned value_size=0;
357
+ int res = 0;
358
+
359
+ DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
360
+ curr_attr = (Dwarf_Half) utmp3;
361
+ DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
362
+ curr_attr_form = (Dwarf_Half) utmp3;
363
+ if (curr_attr_form == DW_FORM_indirect) {
364
+ Dwarf_Unsigned utmp6;
365
+
366
+ /* DECODE_LEB128_UWORD updates info_ptr */
367
+ DECODE_LEB128_UWORD(info_ptr, utmp6);
368
+ curr_attr_form = (Dwarf_Half) utmp6;
369
+ }
370
+
371
+ if (curr_attr == attr) {
372
+ *attr_form = curr_attr_form;
373
+ *ptr_to_value = info_ptr;
374
+ return DW_DLV_OK;
375
+ }
376
+
377
+ res = _dwarf_get_size_of_val(dbg,
378
+ curr_attr_form,
379
+ die->di_cu_context->cc_version_stamp,
380
+ die->di_cu_context->cc_address_size,
381
+ info_ptr,
382
+ die->di_cu_context->cc_length_size,
383
+ &value_size,
384
+ error);
385
+ if (res != DW_DLV_OK) {
386
+ return res;
387
+ }
388
+ if ( (die_info_end - info_ptr) < value_size) {
389
+ /* Something badly wrong. We point past end
390
+ of debug_info or debug_types . */
391
+ _dwarf_error(dbg,error,DW_DLE_DIE_ABBREV_BAD);
392
+ return DW_DLV_ERROR;
393
+ }
394
+ info_ptr+= value_size;
395
+ } while (curr_attr != 0 || curr_attr_form != 0);
396
+ return DW_DLV_NO_ENTRY;
397
+ }
398
+
399
+
400
+ int
401
+ dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error)
402
+ {
403
+ Dwarf_Half attr_form = 0;
404
+ Dwarf_Debug dbg = 0;
405
+ Dwarf_Byte_Ptr info_ptr = 0;
406
+ Dwarf_Unsigned string_offset = 0;
407
+ int res = DW_DLV_ERROR;
408
+
409
+ CHECK_DIE(die, DW_DLV_ERROR);
410
+
411
+ res = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form,&info_ptr,error);
412
+ if (res == DW_DLV_ERROR) {
413
+ return res;
414
+ }
415
+ if (res == DW_DLV_NO_ENTRY){
416
+ return res;
417
+ }
418
+
419
+ if (attr_form == DW_FORM_string) {
420
+ *ret_name = (char *) (info_ptr);
421
+ return DW_DLV_OK;
422
+ }
423
+
424
+ dbg = die->di_cu_context->cc_dbg;
425
+ if (attr_form == DW_FORM_GNU_str_index ||
426
+ attr_form == DW_FORM_strx) {
427
+ Dwarf_CU_Context context = die->di_cu_context;
428
+ Dwarf_Unsigned offsettostr= 0;
429
+
430
+ res = _dwarf_extract_string_offset_via_str_offsets(dbg,
431
+ info_ptr,
432
+ DW_AT_name,
433
+ attr_form,
434
+ context,
435
+ &offsettostr,
436
+ error);
437
+ if (res != DW_DLV_OK) {
438
+ return res;
439
+ }
440
+ string_offset = offsettostr;
441
+ }
442
+
443
+
444
+ if (attr_form != DW_FORM_strp && attr_form != DW_FORM_GNU_str_index) {
445
+ _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
446
+ return (DW_DLV_ERROR);
447
+ }
448
+ if( attr_form == DW_FORM_strp) {
449
+ READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned,
450
+ info_ptr, die->di_cu_context->cc_length_size);
451
+
452
+ }
453
+
454
+ if (string_offset >= dbg->de_debug_str.dss_size) {
455
+ _dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD);
456
+ return (DW_DLV_ERROR);
457
+ }
458
+
459
+ res = _dwarf_load_section(dbg, &dbg->de_debug_str,error);
460
+ if (res != DW_DLV_OK) {
461
+ return res;
462
+ }
463
+ if (!dbg->de_debug_str.dss_size) {
464
+ return (DW_DLV_NO_ENTRY);
465
+ }
466
+
467
+ *ret_name = (char *) (dbg->de_debug_str.dss_data + string_offset);
468
+ return DW_DLV_OK;
469
+ }
470
+
471
+
472
+ int
473
+ dwarf_hasattr(Dwarf_Die die,
474
+ Dwarf_Half attr,
475
+ Dwarf_Bool * return_bool, Dwarf_Error * error)
476
+ {
477
+ Dwarf_Half attr_form = 0;
478
+ Dwarf_Byte_Ptr info_ptr = 0;
479
+ int res = 0;
480
+
481
+ CHECK_DIE(die, DW_DLV_ERROR);
482
+
483
+ res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr,error);
484
+ if(res == DW_DLV_ERROR) {
485
+ return res;
486
+ }
487
+ if(res == DW_DLV_NO_ENTRY) {
488
+ *return_bool = false;
489
+ return DW_DLV_OK;
490
+ }
491
+ *return_bool = (true);
492
+ return DW_DLV_OK;
493
+ }
494
+
495
+ int
496
+ dwarf_attr(Dwarf_Die die,
497
+ Dwarf_Half attr,
498
+ Dwarf_Attribute * ret_attr, Dwarf_Error * error)
499
+ {
500
+ Dwarf_Half attr_form = 0;
501
+ Dwarf_Attribute attrib = 0;
502
+ Dwarf_Byte_Ptr info_ptr = 0;
503
+ Dwarf_Debug dbg = 0;
504
+ int res = 0;
505
+
506
+ CHECK_DIE(die, DW_DLV_ERROR);
507
+ dbg = die->di_cu_context->cc_dbg;
508
+
509
+ res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr,error);
510
+ if(res == DW_DLV_ERROR) {
511
+ return res;
512
+ }
513
+ if(res == DW_DLV_NO_ENTRY) {
514
+ return res;
515
+ }
516
+
517
+
518
+ attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
519
+ if (attrib == NULL) {
520
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
521
+ return (DW_DLV_ERROR);
522
+ }
523
+
524
+ attrib->ar_attribute = attr;
525
+ attrib->ar_attribute_form = attr_form;
526
+ attrib->ar_attribute_form_direct = attr_form;
527
+ attrib->ar_cu_context = die->di_cu_context;
528
+ attrib->ar_debug_ptr = info_ptr;
529
+ attrib->ar_die = die;
530
+ *ret_attr = (attrib);
531
+ return DW_DLV_OK;
532
+ }
533
+
534
+ /* A DWP (.dwp) package object never contains .debug_addr,
535
+ only a normal .o or executable object.
536
+ Error returned here is on dbg, not tieddbg. */
537
+ int
538
+ _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg,
539
+ Dwarf_CU_Context context,
540
+ Dwarf_Unsigned index_to_addr,
541
+ Dwarf_Addr *addr_out,
542
+ Dwarf_Error *error)
543
+ {
544
+ Dwarf_Unsigned address_base = 0;
545
+ Dwarf_Unsigned addrindex = index_to_addr;
546
+ Dwarf_Unsigned addr_offset = 0;
547
+ Dwarf_Unsigned ret_addr = 0;
548
+ int res = 0;
549
+
550
+ res = _dwarf_get_address_base_attr_value(dbg,context,
551
+ &address_base, error);
552
+ if (res != DW_DLV_OK) {
553
+ return res;
554
+ }
555
+ res = _dwarf_load_section(dbg, &dbg->de_debug_addr,error);
556
+ if (res != DW_DLV_OK) {
557
+ /* Ignore the inner error, report something meaningful */
558
+ if (res == DW_DLV_ERROR) {
559
+ dwarf_dealloc(dbg,*error, DW_DLA_ERROR);
560
+ *error = 0;
561
+ }
562
+ _dwarf_error(dbg,error,
563
+ DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION);
564
+ return DW_DLV_ERROR;
565
+ }
566
+ /* DW_FORM_addrx has a base value from the CU die:
567
+ DW_AT_addr_base. DW_OP_addrx and DW_OP_constx
568
+ rely on DW_AT_addr_base too. */
569
+ /* DW_FORM_GNU_addr_index relies on DW_AT_GNU_addr_base
570
+ which is in the CU die. */
571
+
572
+ addr_offset = address_base + (addrindex * context->cc_address_size);
573
+
574
+
575
+ /* The offsets table is a series of address-size entries
576
+ but with a base. */
577
+ if ((addr_offset + context->cc_address_size) >
578
+ dbg->de_debug_addr.dss_size ) {
579
+ _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
580
+ return (DW_DLV_ERROR);
581
+ }
582
+
583
+ READ_UNALIGNED(dbg,ret_addr,Dwarf_Addr,
584
+ dbg->de_debug_addr.dss_data + addr_offset,
585
+ context->cc_address_size);
586
+ *addr_out = ret_addr;
587
+ return DW_DLV_OK;
588
+ }
589
+
590
+ int
591
+ _dwarf_look_in_local_and_tied_by_index(
592
+ Dwarf_Debug dbg,
593
+ Dwarf_CU_Context context,
594
+ Dwarf_Unsigned index,
595
+ Dwarf_Addr *return_addr,
596
+ Dwarf_Error *error)
597
+ {
598
+ int res2 = 0;
599
+
600
+ res2 = _dwarf_extract_address_from_debug_addr(dbg,
601
+ context, index, return_addr, error);
602
+ if (res2 != DW_DLV_OK) {
603
+ if (res2 == DW_DLV_ERROR &&dwarf_errno(*error) ==
604
+ DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION
605
+ && dbg->de_tied_data.td_tied_object) {
606
+ int res3 = 0;
607
+
608
+ /* We do not want to leak error structs... */
609
+ dwarf_dealloc(dbg,*error,DW_DLA_ERROR);
610
+
611
+ *error = 0;
612
+ /* error is returned on dbg, not tieddbg. */
613
+ res3 = _dwarf_get_addr_from_tied(dbg,
614
+ context,index,return_addr,error);
615
+ if ( res3 == DW_DLV_ERROR) {
616
+ return res3;
617
+ } else if ( res3 == DW_DLV_NO_ENTRY) {
618
+ return res3;
619
+ }
620
+ } else {
621
+ return res2;
622
+ }
623
+ }
624
+ return (DW_DLV_OK);
625
+ }
626
+
627
+ /* The DIE here can be any DIE in the relevant CU.
628
+ index is an index into .debug_addr */
629
+ int
630
+ dwarf_debug_addr_index_to_addr(Dwarf_Die die,
631
+ Dwarf_Unsigned index,
632
+ Dwarf_Addr *return_addr,
633
+ Dwarf_Error *error)
634
+ {
635
+ Dwarf_Debug dbg = 0;
636
+ Dwarf_CU_Context context = 0;
637
+ int res = 0;
638
+
639
+
640
+ CHECK_DIE(die, DW_DLV_ERROR);
641
+ context = die->di_cu_context;
642
+ dbg = context->cc_dbg;
643
+
644
+ /* error is returned on dbg, not tieddbg. */
645
+ res = _dwarf_look_in_local_and_tied_by_index(dbg,
646
+ context,
647
+ index,
648
+ return_addr,
649
+ error);
650
+ return res;
651
+ }
652
+ /* ASSERT:
653
+ attr_form == DW_FORM_GNU_addr_index ||
654
+ attr_form == DW_FORM_addrx
655
+ */
656
+ int
657
+ _dwarf_look_in_local_and_tied(Dwarf_Half attr_form,
658
+ Dwarf_CU_Context context,
659
+ Dwarf_Small *info_ptr,
660
+ Dwarf_Addr *return_addr,
661
+ Dwarf_Error *error)
662
+ {
663
+ int res2 = 0;
664
+ Dwarf_Unsigned index_to_addr = 0;
665
+ Dwarf_Debug dbg = 0;
666
+
667
+ /* We get the index. It might apply here
668
+ or in tied object. Checking that next. */
669
+ res2 = _dwarf_get_addr_index_itself(attr_form,
670
+ info_ptr,&index_to_addr,error);
671
+ if(res2 != DW_DLV_OK) {
672
+ return res2;
673
+ }
674
+ dbg = context->cc_dbg;
675
+ /* error is returned on dbg, not tieddbg. */
676
+ res2 = _dwarf_look_in_local_and_tied_by_index(
677
+ dbg,context,index_to_addr,return_addr,error);
678
+ return res2;
679
+
680
+ }
681
+
682
+ int
683
+ dwarf_lowpc(Dwarf_Die die,
684
+ Dwarf_Addr * return_addr,
685
+ Dwarf_Error * error)
686
+ {
687
+ Dwarf_Addr ret_addr = 0;
688
+ Dwarf_Byte_Ptr info_ptr = 0;
689
+ Dwarf_Half attr_form = 0;
690
+ Dwarf_Debug dbg = 0;
691
+ Dwarf_Half address_size = 0;
692
+ Dwarf_Half offset_size = 0;
693
+ int version = 0;
694
+ enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN;
695
+ int res = 0;
696
+ Dwarf_CU_Context context = die->di_cu_context;
697
+
698
+ CHECK_DIE(die, DW_DLV_ERROR);
699
+
700
+ dbg = context->cc_dbg;
701
+ address_size = context->cc_address_size;
702
+ offset_size = context->cc_length_size;
703
+ res = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form,&info_ptr,error);
704
+ if(res == DW_DLV_ERROR) {
705
+ return res;
706
+ }
707
+ if(res == DW_DLV_NO_ENTRY) {
708
+ return res;
709
+ }
710
+ version = context->cc_version_stamp;
711
+ class = dwarf_get_form_class(version,DW_AT_low_pc,
712
+ offset_size,attr_form);
713
+ if (class != DW_FORM_CLASS_ADDRESS) {
714
+ /* Not the correct form for DW_AT_low_pc */
715
+ _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
716
+ return (DW_DLV_ERROR);
717
+ }
718
+
719
+ if(attr_form == DW_FORM_GNU_addr_index ||
720
+ attr_form == DW_FORM_addrx) {
721
+ /* error is returned on dbg, not tieddbg. */
722
+ res = _dwarf_look_in_local_and_tied(
723
+ attr_form,
724
+ context,
725
+ info_ptr,
726
+ return_addr,
727
+ error);
728
+ return res;
729
+ }
730
+ READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
731
+ info_ptr, address_size);
732
+
733
+ *return_addr = ret_addr;
734
+ return (DW_DLV_OK);
735
+ }
736
+
737
+
738
+ /* This works for DWARF2 and DWARF3 but fails for DWARF4
739
+ DW_AT_high_pc attributes of class constant.
740
+ It is best to cease using this interface.
741
+ */
742
+ int
743
+ dwarf_highpc(Dwarf_Die die,
744
+ Dwarf_Addr * return_addr, Dwarf_Error * error)
745
+ {
746
+ int res = 0;
747
+ enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN;
748
+ Dwarf_Half form = 0;
749
+
750
+ CHECK_DIE(die, DW_DLV_ERROR);
751
+ res = dwarf_highpc_b(die,return_addr,&form,&class,error);
752
+ if (res != DW_DLV_OK) {
753
+ return res;
754
+ }
755
+ if (form != DW_FORM_addr) {
756
+ /* Not the correct form for DWARF2/3 DW_AT_high_pc */
757
+ Dwarf_Debug dbg = die->di_cu_context->cc_dbg;
758
+ _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
759
+ return (DW_DLV_ERROR);
760
+ }
761
+ return (DW_DLV_OK);
762
+ }
763
+
764
+
765
+ int
766
+ _dwarf_get_string_base_attr_value(Dwarf_Debug dbg,
767
+ Dwarf_CU_Context context,
768
+ Dwarf_Unsigned *sbase_out,
769
+ Dwarf_Error *error)
770
+ {
771
+ int res = 0;
772
+ Dwarf_Die cudie = 0;
773
+ Dwarf_Small *cu_die_dataptr = 0;
774
+ Dwarf_Unsigned cu_die_offset = 0;
775
+ Dwarf_Attribute myattr = 0;
776
+
777
+ if(context->cc_str_offsets_base_present) {
778
+ *sbase_out = context->cc_str_offsets_base;
779
+ return DW_DLV_OK;
780
+ }
781
+ cu_die_offset = context->cc_cu_die_global_sec_offset;
782
+ context->cc_cu_die_offset_present = TRUE;
783
+ if(!cu_die_dataptr) {
784
+ _dwarf_error(dbg, error,
785
+ DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM);
786
+ return (DW_DLV_ERROR);
787
+
788
+ }
789
+ res = dwarf_offdie_b(dbg,cu_die_offset,
790
+ context->cc_is_info,
791
+ &cudie,
792
+ error);
793
+ if(res != DW_DLV_OK) {
794
+ return res;
795
+ }
796
+ res = dwarf_attr(cudie,DW_AT_str_offsets_base,
797
+ &myattr,error);
798
+ if(res == DW_DLV_ERROR) {
799
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
800
+ return res;
801
+ }
802
+ if (res == DW_DLV_OK) {
803
+ Dwarf_Unsigned val = 0;
804
+ res = dwarf_formudata(myattr,&val,error);
805
+ dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
806
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
807
+ if(res != DW_DLV_OK) {
808
+ return res;
809
+ }
810
+ *sbase_out = val;
811
+ context->cc_str_offsets_base = val;
812
+ context->cc_str_offsets_base_present = TRUE;
813
+ return DW_DLV_OK;
814
+ }
815
+ /* NO ENTRY, No other attr.Not even GNU, this one is standard
816
+ DWARF5 only. */
817
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
818
+ /* We do not need a base for a .dwo. We might for .dwp
819
+ and would or .o or executable.
820
+ FIXME: assume we do not need this.
821
+ Should we really return DW_DLV_NO_ENTRY?
822
+ */
823
+ *sbase_out = 0;
824
+ return DW_DLV_OK;
825
+ }
826
+ /* Goes to the CU die and finds the DW_AT_GNU_addr_base
827
+ (or DW_AT_addr_base ) and gets the value from that CU die
828
+ and returns it thou abase_out. If we cannot find the value
829
+ it is a serious error in the DWARF.
830
+ */
831
+ static int
832
+ _dwarf_get_address_base_attr_value(Dwarf_Debug dbg,
833
+ Dwarf_CU_Context context,
834
+ Dwarf_Unsigned *abase_out,
835
+ Dwarf_Error *error)
836
+ {
837
+ int res = 0;
838
+ Dwarf_Die cudie = 0;
839
+ Dwarf_Bool cu_die_offset_present = 0;
840
+ Dwarf_Unsigned cu_die_offset = 0;
841
+ Dwarf_Attribute myattr = 0;
842
+ if(context->cc_addr_base_present) {
843
+ *abase_out = context->cc_addr_base;
844
+ return DW_DLV_OK;
845
+ }
846
+
847
+ cu_die_offset = context->cc_cu_die_global_sec_offset;
848
+ cu_die_offset_present = context->cc_cu_die_offset_present;
849
+ if(!cu_die_offset_present) {
850
+ _dwarf_error(dbg, error,
851
+ DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM);
852
+ return (DW_DLV_ERROR);
853
+
854
+ }
855
+ res = dwarf_offdie_b(dbg,cu_die_offset,
856
+ context->cc_is_info,
857
+ &cudie,
858
+ error);
859
+ if(res != DW_DLV_OK) {
860
+ return res;
861
+ }
862
+ res = dwarf_attr(cudie,DW_AT_addr_base,
863
+ &myattr,error);
864
+ if(res == DW_DLV_ERROR) {
865
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
866
+ return res;
867
+ }
868
+ if (res == DW_DLV_OK) {
869
+ Dwarf_Unsigned val = 0;
870
+ res = dwarf_formudata(myattr,&val,error);
871
+ dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
872
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
873
+ if(res != DW_DLV_OK) {
874
+ return res;
875
+ }
876
+ *abase_out = val;
877
+ return DW_DLV_OK;
878
+ }
879
+ /* NO ENTRY, try the other attr. */
880
+ res = dwarf_attr(cudie,DW_AT_GNU_addr_base, &myattr,error);
881
+ if(res == DW_DLV_NO_ENTRY) {
882
+ res = dwarf_attr(cudie,DW_AT_addr_base, &myattr,error);
883
+ if (res == DW_DLV_NO_ENTRY) {
884
+ /* A .o or .dwp needs a base, but a .dwo does not.
885
+ FIXME: check this claim...
886
+ Assume zero is ok and works. */
887
+ *abase_out = 0;
888
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
889
+ return DW_DLV_OK;
890
+ }
891
+ if (res == DW_DLV_ERROR) {
892
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
893
+ return res;
894
+ }
895
+ } else if (res == DW_DLV_ERROR) {
896
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
897
+ return res;
898
+ }
899
+
900
+ {
901
+ Dwarf_Unsigned val = 0;
902
+ res = dwarf_formudata(myattr,&val,error);
903
+ dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
904
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
905
+ if(res != DW_DLV_OK) {
906
+ return res;
907
+ }
908
+ *abase_out = val;
909
+ }
910
+ return DW_DLV_OK;
911
+ }
912
+
913
+
914
+ /* The dbg here will be the tieddbg, and context will be
915
+ a tied context. */
916
+ static int
917
+ _dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg,
918
+ Dwarf_CU_Context context,
919
+ Dwarf_Unsigned * rangesbase_out,
920
+ Dwarf_Error * error)
921
+ {
922
+ int res = 0;
923
+ Dwarf_Die cudie = 0;
924
+ Dwarf_Bool cu_die_offset_present = 0;
925
+ Dwarf_Unsigned cu_die_offset = 0;
926
+ Dwarf_Attribute myattr = 0;
927
+ if(context->cc_ranges_base_present) {
928
+ *rangesbase_out = context->cc_ranges_base;
929
+ return DW_DLV_OK;
930
+ }
931
+
932
+ cu_die_offset = context->cc_cu_die_global_sec_offset;
933
+ cu_die_offset_present = context->cc_cu_die_offset_present;
934
+ if(!cu_die_offset_present) {
935
+ _dwarf_error(dbg, error,
936
+ DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM);
937
+ return (DW_DLV_ERROR);
938
+
939
+ }
940
+ res = dwarf_offdie_b(dbg,cu_die_offset,
941
+ context->cc_is_info,
942
+ &cudie,
943
+ error);
944
+ if(res != DW_DLV_OK) {
945
+ return res;
946
+ }
947
+ res = dwarf_attr(cudie,DW_AT_ranges_base,
948
+ &myattr,error);
949
+ if(res == DW_DLV_ERROR) {
950
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
951
+ return res;
952
+ }
953
+ if (res == DW_DLV_OK) {
954
+ Dwarf_Unsigned val = 0;
955
+ res = dwarf_formudata(myattr,&val,error);
956
+ dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
957
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
958
+ if(res != DW_DLV_OK) {
959
+ return res;
960
+ }
961
+ *rangesbase_out = val;
962
+ return DW_DLV_OK;
963
+ }
964
+ /* NO ENTRY, try the other attr. */
965
+ res = dwarf_attr(cudie,DW_AT_GNU_ranges_base, &myattr,error);
966
+ if(res == DW_DLV_NO_ENTRY) {
967
+ res = dwarf_attr(cudie,DW_AT_ranges_base, &myattr,error);
968
+ if (res == DW_DLV_NO_ENTRY) {
969
+ /* A .o or execeutable skeleton needs
970
+ a base , but a .dwo does not.
971
+ Assume zero is ok and works. */
972
+ *rangesbase_out = 0;
973
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
974
+ return DW_DLV_OK;
975
+ }
976
+ if (res == DW_DLV_ERROR) {
977
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
978
+ return res;
979
+ }
980
+ } else if (res == DW_DLV_ERROR) {
981
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
982
+ return res;
983
+ }
984
+
985
+ {
986
+ Dwarf_Unsigned val = 0;
987
+ res = dwarf_formudata(myattr,&val,error);
988
+ dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
989
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
990
+ if(res != DW_DLV_OK) {
991
+ return res;
992
+ }
993
+ *rangesbase_out = val;
994
+ }
995
+ return DW_DLV_OK;
996
+ }
997
+ /* This works for all versions of DWARF.
998
+ This is the preferred interface, cease using dwarf_highpc.
999
+ The consumer has to check the return_form or
1000
+ return_class to decide if the value returned
1001
+ through return_value is an address or an address-offset.
1002
+
1003
+ See DWARF4 section 2.17.2,
1004
+ "Contiguous Address Range".
1005
+ */
1006
+ int
1007
+ dwarf_highpc_b(Dwarf_Die die,
1008
+ Dwarf_Addr * return_value,
1009
+ Dwarf_Half * return_form,
1010
+ enum Dwarf_Form_Class * return_class,
1011
+ Dwarf_Error * error)
1012
+ {
1013
+ Dwarf_Byte_Ptr info_ptr = 0;
1014
+ Dwarf_Half attr_form = 0;
1015
+ Dwarf_Debug dbg = 0;
1016
+ Dwarf_Half address_size = 0;
1017
+ Dwarf_Half offset_size = 0;
1018
+ enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN;
1019
+ Dwarf_Half version = 0;
1020
+ int res = 0;
1021
+
1022
+ CHECK_DIE(die, DW_DLV_ERROR);
1023
+ dbg = die->di_cu_context->cc_dbg;
1024
+ address_size = die->di_cu_context->cc_address_size;
1025
+
1026
+ res = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form,&info_ptr,error);
1027
+ if(res == DW_DLV_ERROR) {
1028
+ return res;
1029
+ }
1030
+ if(res == DW_DLV_NO_ENTRY) {
1031
+ return res;
1032
+ }
1033
+
1034
+ version = die->di_cu_context->cc_version_stamp;
1035
+ offset_size = die->di_cu_context->cc_length_size;
1036
+ class = dwarf_get_form_class(version,DW_AT_high_pc,
1037
+ offset_size,attr_form);
1038
+
1039
+ if (class == DW_FORM_CLASS_ADDRESS) {
1040
+ Dwarf_Addr addr = 0;
1041
+ if (attr_form == DW_FORM_GNU_addr_index ||
1042
+ attr_form == DW_FORM_addrx) {
1043
+ Dwarf_Unsigned addr_out = 0;
1044
+ Dwarf_Unsigned index_to_addr = 0;
1045
+ int res2 = 0;
1046
+ Dwarf_CU_Context context = die->di_cu_context;
1047
+
1048
+ /* index_to_addr we get here might apply
1049
+ to this dbg or to tieddbg. */
1050
+ /* error is returned on dbg, not tied */
1051
+ res2 = _dwarf_get_addr_index_itself(attr_form,
1052
+ info_ptr,&index_to_addr,error);
1053
+ if(res2 != DW_DLV_OK) {
1054
+ return res2;
1055
+ }
1056
+
1057
+ res2 = _dwarf_extract_address_from_debug_addr(dbg,
1058
+ context,
1059
+ index_to_addr,
1060
+ &addr_out,
1061
+ error);
1062
+ if(res2 != DW_DLV_OK) {
1063
+ if (res2 == DW_DLV_ERROR &&
1064
+ dwarf_errno(*error) ==
1065
+ DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION
1066
+ && dbg->de_tied_data.td_tied_object) {
1067
+ /* .debug_addr is in tied dbg. */
1068
+ int res3 = 0;
1069
+
1070
+ /* Do not leak the above error pointer,
1071
+ we have something else to try here. */
1072
+ dwarf_dealloc(dbg,*error, DW_DLA_ERROR);
1073
+ *error = 0;
1074
+
1075
+ /* .debug_addr is in tied dbg.
1076
+ Get the index of the addr */
1077
+ res3 = _dwarf_get_addr_from_tied(dbg,
1078
+ context,index_to_addr,&addr_out,error);
1079
+ if ( res3 != DW_DLV_OK) {
1080
+ return res3;
1081
+ }
1082
+ } else {
1083
+ return res2;
1084
+ }
1085
+ }
1086
+ *return_value = addr_out;
1087
+ *return_form = attr_form;
1088
+ *return_class = class;
1089
+ return (DW_DLV_OK);
1090
+ }
1091
+
1092
+ READ_UNALIGNED(dbg, addr, Dwarf_Addr,
1093
+ info_ptr, address_size);
1094
+ *return_value = addr;
1095
+ } else {
1096
+ int res3 = 0;
1097
+ Dwarf_Unsigned v = 0;
1098
+ res3 = _dwarf_die_attr_unsigned_constant(die,DW_AT_high_pc,
1099
+ &v,error);
1100
+ if(res3 != DW_DLV_OK) {
1101
+ Dwarf_Byte_Ptr info_ptr2 = 0;
1102
+ res3 = _dwarf_get_value_ptr(die, DW_AT_high_pc,
1103
+ &attr_form,&info_ptr2,error);
1104
+ if(res3 == DW_DLV_ERROR) {
1105
+ return res3;
1106
+ }
1107
+ if(res == DW_DLV_NO_ENTRY) {
1108
+ return res3;
1109
+ }
1110
+ if (attr_form == DW_FORM_sdata) {
1111
+ Dwarf_Signed sval = 0;
1112
+ sval = _dwarf_decode_s_leb128(info_ptr2, NULL);
1113
+ /* DWARF4 defines the value as an unsigned offset
1114
+ in section 2.17.2. */
1115
+ *return_value = (Dwarf_Unsigned)sval;
1116
+ } else {
1117
+ _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
1118
+ return (DW_DLV_ERROR);
1119
+ }
1120
+ } else {
1121
+ *return_value = v;
1122
+ }
1123
+ }
1124
+ *return_form = attr_form;
1125
+ *return_class = class;
1126
+ return (DW_DLV_OK);
1127
+ }
1128
+
1129
+ /* The dbg and context here are a file with DW_FORM_addrx
1130
+ but missing .debug_addr. So go to the tied file
1131
+ and using the signature from the current context
1132
+ locate the target CU in the tied file Then
1133
+ get the address.
1134
+
1135
+ */
1136
+ int
1137
+ _dwarf_get_addr_from_tied(Dwarf_Debug dbg,
1138
+ Dwarf_CU_Context context,
1139
+ Dwarf_Unsigned index,
1140
+ Dwarf_Addr *addr_out,
1141
+ Dwarf_Error*error)
1142
+ {
1143
+ Dwarf_Debug tieddbg = 0;
1144
+ int res = 0;
1145
+ Dwarf_Addr local_addr = 0;
1146
+ Dwarf_CU_Context tiedcontext = 0;
1147
+
1148
+ if (!context->cc_signature_present) {
1149
+ _dwarf_error(dbg, error, DW_DLE_NO_SIGNATURE_TO_LOOKUP);
1150
+ return DW_DLV_ERROR;
1151
+ }
1152
+ tieddbg = dbg->de_tied_data.td_tied_object;
1153
+ if (!tieddbg) {
1154
+ _dwarf_error(dbg, error, DW_DLE_NO_TIED_ADDR_AVAILABLE);
1155
+ return DW_DLV_ERROR;
1156
+ }
1157
+ if (!context->cc_signature_present) {
1158
+ _dwarf_error(dbg, error, DW_DLE_NO_TIED_SIG_AVAILABLE);
1159
+ return DW_DLV_ERROR;
1160
+ }
1161
+ res = _dwarf_search_for_signature(tieddbg,
1162
+ context->cc_type_signature,
1163
+ &tiedcontext,
1164
+ error);
1165
+ if ( res == DW_DLV_ERROR) {
1166
+ /* Associate the error with dbg, not tieddbg */
1167
+ _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1168
+ return res;
1169
+ } else if ( res == DW_DLV_NO_ENTRY) {
1170
+ return res;
1171
+ }
1172
+
1173
+ res = _dwarf_extract_address_from_debug_addr(tieddbg,
1174
+ tiedcontext,
1175
+ index,
1176
+ &local_addr,
1177
+ error);
1178
+ if ( res == DW_DLV_ERROR) {
1179
+ /* Associate the error with dbg, not tidedbg */
1180
+ _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1181
+ return res;
1182
+ } else if ( res == DW_DLV_NO_ENTRY) {
1183
+ return res;
1184
+ }
1185
+ *addr_out = local_addr;
1186
+ return DW_DLV_OK;
1187
+ }
1188
+
1189
+ int
1190
+ _dwarf_get_ranges_base_attr_from_tied(Dwarf_Debug dbg,
1191
+ Dwarf_CU_Context context,
1192
+ Dwarf_Unsigned *tiedbase_out,
1193
+ Dwarf_Error*error)
1194
+ {
1195
+ Dwarf_Debug tieddbg = 0;
1196
+ int res = 0;
1197
+ Dwarf_Unsigned tiedbase= 0;
1198
+ Dwarf_CU_Context tiedcontext = 0;
1199
+
1200
+ if (!context->cc_signature_present) {
1201
+ _dwarf_error(dbg, error, DW_DLE_NO_SIGNATURE_TO_LOOKUP);
1202
+ return DW_DLV_ERROR;
1203
+ }
1204
+ tieddbg = dbg->de_tied_data.td_tied_object;
1205
+ if (!tieddbg) {
1206
+ _dwarf_error(dbg, error, DW_DLE_NO_TIED_ADDR_AVAILABLE);
1207
+ return DW_DLV_ERROR;
1208
+ }
1209
+ if (!context->cc_signature_present) {
1210
+ _dwarf_error(dbg, error, DW_DLE_NO_TIED_SIG_AVAILABLE);
1211
+ return DW_DLV_ERROR;
1212
+ }
1213
+ res = _dwarf_search_for_signature(tieddbg,
1214
+ context->cc_type_signature,
1215
+ &tiedcontext,
1216
+ error);
1217
+ if ( res == DW_DLV_ERROR) {
1218
+ /* Associate the error with dbg, not tidedbg */
1219
+ _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1220
+ return res;
1221
+ } else if ( res != DW_DLV_NO_ENTRY) {
1222
+ return res;
1223
+ }
1224
+ res = _dwarf_get_ranges_base_attr_value(tieddbg, tiedcontext,
1225
+ &tiedbase, error);
1226
+ if (res != DW_DLV_OK) {
1227
+ /* Associate the error with dbg, not tidedbg */
1228
+ _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1229
+ return res;
1230
+ }
1231
+ *tiedbase_out = tiedbase;
1232
+ return DW_DLV_OK;
1233
+ }
1234
+
1235
+
1236
+ /*
1237
+ Takes a die, an attribute attr, and checks if attr
1238
+ occurs in die. Attr is required to be an attribute
1239
+ whose form is in the "constant" class. If attr occurs
1240
+ in die, the value is returned.
1241
+
1242
+ Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as
1243
+ appropriate. Sets the value thru the pointer return_val.
1244
+
1245
+ This function is meant to do all the
1246
+ processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset,
1247
+ and dwarf_srclang. And it helps in dwarf_highpc_with_form().
1248
+ */
1249
+ static int
1250
+ _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
1251
+ Dwarf_Half attr,
1252
+ Dwarf_Unsigned * return_val,
1253
+ Dwarf_Error * error)
1254
+ {
1255
+ Dwarf_Byte_Ptr info_ptr = 0;
1256
+ Dwarf_Half attr_form = 0;
1257
+ Dwarf_Unsigned ret_value = 0;
1258
+ Dwarf_Debug dbg = 0;
1259
+ int res = 0;
1260
+
1261
+ CHECK_DIE(die, DW_DLV_ERROR);
1262
+
1263
+ dbg = die->di_cu_context->cc_dbg;
1264
+ res = _dwarf_get_value_ptr(die,attr,&attr_form,
1265
+ &info_ptr,error);
1266
+ if(res != DW_DLV_OK) {
1267
+ return res;
1268
+ }
1269
+ switch (attr_form) {
1270
+ case DW_FORM_data1:
1271
+ *return_val = (*(Dwarf_Small *) info_ptr);
1272
+ return (DW_DLV_OK);
1273
+
1274
+ case DW_FORM_data2:
1275
+ READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
1276
+ info_ptr, sizeof(Dwarf_Shalf));
1277
+ *return_val = ret_value;
1278
+ return (DW_DLV_OK);
1279
+
1280
+ case DW_FORM_data4:
1281
+ READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
1282
+ info_ptr, sizeof(Dwarf_sfixed));
1283
+ *return_val = ret_value;
1284
+ return (DW_DLV_OK);
1285
+
1286
+ case DW_FORM_data8:
1287
+ READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
1288
+ info_ptr, sizeof(Dwarf_Unsigned));
1289
+ *return_val = ret_value;
1290
+ return (DW_DLV_OK);
1291
+
1292
+ case DW_FORM_udata:
1293
+ *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL));
1294
+ return (DW_DLV_OK);
1295
+
1296
+ default:
1297
+ _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
1298
+ return (DW_DLV_ERROR);
1299
+ }
1300
+ }
1301
+
1302
+
1303
+ int
1304
+ dwarf_bytesize(Dwarf_Die die,
1305
+ Dwarf_Unsigned * ret_size, Dwarf_Error * error)
1306
+ {
1307
+ Dwarf_Unsigned luns = 0;
1308
+ int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size,
1309
+ &luns, error);
1310
+ *ret_size = luns;
1311
+ return res;
1312
+ }
1313
+
1314
+
1315
+ int
1316
+ dwarf_bitsize(Dwarf_Die die,
1317
+ Dwarf_Unsigned * ret_size, Dwarf_Error * error)
1318
+ {
1319
+ Dwarf_Unsigned luns = 0;
1320
+ int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size,
1321
+ &luns, error);
1322
+ *ret_size = luns;
1323
+ return res;
1324
+ }
1325
+
1326
+
1327
+ int
1328
+ dwarf_bitoffset(Dwarf_Die die,
1329
+ Dwarf_Unsigned * ret_size, Dwarf_Error * error)
1330
+ {
1331
+ Dwarf_Unsigned luns = 0;
1332
+ int res = _dwarf_die_attr_unsigned_constant(die,
1333
+ DW_AT_bit_offset, &luns, error);
1334
+ *ret_size = luns;
1335
+ return res;
1336
+ }
1337
+
1338
+
1339
+ /* Refer section 3.1, page 21 in Dwarf Definition. */
1340
+ int
1341
+ dwarf_srclang(Dwarf_Die die,
1342
+ Dwarf_Unsigned * ret_size, Dwarf_Error * error)
1343
+ {
1344
+ Dwarf_Unsigned luns = 0;
1345
+ int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_language,
1346
+ &luns, error);
1347
+ *ret_size = luns;
1348
+ return res;
1349
+ }
1350
+
1351
+
1352
+ /* Refer section 5.4, page 37 in Dwarf Definition. */
1353
+ int
1354
+ dwarf_arrayorder(Dwarf_Die die,
1355
+ Dwarf_Unsigned * ret_size, Dwarf_Error * error)
1356
+ {
1357
+ Dwarf_Unsigned luns = 0;
1358
+ int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering,
1359
+ &luns, error);
1360
+ *ret_size = luns;
1361
+ return res;
1362
+ }
1363
+
1364
+ /* Return DW_DLV_OK if ok
1365
+ DW_DLV_ERROR if failure.
1366
+
1367
+ If the die and the attr are not related the result is
1368
+ meaningless. */
1369
+ int
1370
+ dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr,
1371
+ Dwarf_Off * offset /* return offset thru this ptr */,
1372
+ Dwarf_Error * error)
1373
+ {
1374
+ Dwarf_Off attroff = 0;
1375
+ Dwarf_Small *dataptr = 0;
1376
+ Dwarf_Debug dbg = 0;
1377
+
1378
+ CHECK_DIE(die, DW_DLV_ERROR);
1379
+ dbg = die->di_cu_context->cc_dbg;
1380
+ dataptr = die->di_is_info? dbg->de_debug_info.dss_data:
1381
+ dbg->de_debug_types.dss_data;
1382
+
1383
+ attroff = (attr->ar_debug_ptr - dataptr);
1384
+ *offset = attroff;
1385
+ return DW_DLV_OK;
1386
+ }
1387
+
1388
+ int
1389
+ dwarf_die_abbrev_code(Dwarf_Die die)
1390
+ {
1391
+ return die->di_abbrev_code;
1392
+ }
1393
+
1394
+ /* Returns a flag through ab_has_child. Non-zero if
1395
+ the DIE has children, zero if it does not. */
1396
+ int
1397
+ dwarf_die_abbrev_children_flag(Dwarf_Die die,Dwarf_Half *ab_has_child)
1398
+ {
1399
+ if (die->di_abbrev_list) {
1400
+ *ab_has_child = die->di_abbrev_list->ab_has_child;
1401
+ return DW_DLV_OK;
1402
+ }
1403
+ return DW_DLV_ERROR;
1404
+ }
1405
+
1406
+ /* Helper function for finding form class. */
1407
+ static enum Dwarf_Form_Class
1408
+ dw_get_special_offset(Dwarf_Half attrnum)
1409
+ {
1410
+ switch (attrnum) {
1411
+ case DW_AT_stmt_list:
1412
+ return DW_FORM_CLASS_LINEPTR;
1413
+ case DW_AT_macro_info:
1414
+ return DW_FORM_CLASS_MACPTR;
1415
+ case DW_AT_ranges:
1416
+ return DW_FORM_CLASS_RANGELISTPTR;
1417
+ case DW_AT_location:
1418
+ case DW_AT_string_length:
1419
+ case DW_AT_return_addr:
1420
+ case DW_AT_data_member_location:
1421
+ case DW_AT_frame_base:
1422
+ case DW_AT_segment:
1423
+ case DW_AT_static_link:
1424
+ case DW_AT_use_location:
1425
+ case DW_AT_vtable_elem_location:
1426
+ return DW_FORM_CLASS_LOCLISTPTR;
1427
+ case DW_AT_sibling:
1428
+ case DW_AT_byte_size :
1429
+ case DW_AT_bit_offset :
1430
+ case DW_AT_bit_size :
1431
+ case DW_AT_discr :
1432
+ case DW_AT_import :
1433
+ case DW_AT_common_reference:
1434
+ case DW_AT_containing_type:
1435
+ case DW_AT_default_value:
1436
+ case DW_AT_lower_bound:
1437
+ case DW_AT_bit_stride:
1438
+ case DW_AT_upper_bound:
1439
+ case DW_AT_abstract_origin:
1440
+ case DW_AT_base_types:
1441
+ case DW_AT_count:
1442
+ case DW_AT_friend:
1443
+ case DW_AT_namelist_item:
1444
+ case DW_AT_priority:
1445
+ case DW_AT_specification:
1446
+ case DW_AT_type:
1447
+ case DW_AT_allocated:
1448
+ case DW_AT_associated:
1449
+ case DW_AT_byte_stride:
1450
+ case DW_AT_extension:
1451
+ case DW_AT_trampoline:
1452
+ case DW_AT_small:
1453
+ case DW_AT_object_pointer:
1454
+ case DW_AT_signature:
1455
+ return DW_FORM_CLASS_REFERENCE;
1456
+ case DW_AT_MIPS_fde: /* SGI/IRIX extension */
1457
+ return DW_FORM_CLASS_FRAMEPTR;
1458
+ }
1459
+ return DW_FORM_CLASS_UNKNOWN;
1460
+ }
1461
+
1462
+ /* It takes 4 pieces of data (including the FORM)
1463
+ to accurately determine the form 'class' as documented
1464
+ in the DWARF spec. This is per DWARF4, but will work
1465
+ for DWARF2 or 3 as well. */
1466
+ enum Dwarf_Form_Class dwarf_get_form_class(
1467
+ Dwarf_Half dwversion,
1468
+ Dwarf_Half attrnum,
1469
+ Dwarf_Half offset_size,
1470
+ Dwarf_Half form)
1471
+ {
1472
+ switch (form) {
1473
+ case DW_FORM_addr: return DW_FORM_CLASS_ADDRESS;
1474
+
1475
+ case DW_FORM_data2: return DW_FORM_CLASS_CONSTANT;
1476
+
1477
+ case DW_FORM_data4:
1478
+ if (dwversion <= 3 && offset_size == 4) {
1479
+ enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
1480
+ if (class != DW_FORM_CLASS_UNKNOWN) {
1481
+ return class;
1482
+ }
1483
+ }
1484
+ return DW_FORM_CLASS_CONSTANT;
1485
+ case DW_FORM_data8:
1486
+ if (dwversion <= 3 && offset_size == 8) {
1487
+ enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
1488
+ if (class != DW_FORM_CLASS_UNKNOWN) {
1489
+ return class;
1490
+ }
1491
+ }
1492
+ return DW_FORM_CLASS_CONSTANT;
1493
+
1494
+ case DW_FORM_sec_offset:
1495
+ {
1496
+ enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
1497
+ if (class != DW_FORM_CLASS_UNKNOWN) {
1498
+ return class;
1499
+ }
1500
+ }
1501
+ /* We do not know what this is. */
1502
+ break;
1503
+
1504
+ case DW_FORM_string: return DW_FORM_CLASS_STRING;
1505
+ case DW_FORM_strp: return DW_FORM_CLASS_STRING;
1506
+
1507
+ case DW_FORM_block: return DW_FORM_CLASS_BLOCK;
1508
+ case DW_FORM_block1: return DW_FORM_CLASS_BLOCK;
1509
+ case DW_FORM_block2: return DW_FORM_CLASS_BLOCK;
1510
+ case DW_FORM_block4: return DW_FORM_CLASS_BLOCK;
1511
+
1512
+ case DW_FORM_data1: return DW_FORM_CLASS_CONSTANT;
1513
+ case DW_FORM_sdata: return DW_FORM_CLASS_CONSTANT;
1514
+ case DW_FORM_udata: return DW_FORM_CLASS_CONSTANT;
1515
+
1516
+ case DW_FORM_ref_addr: return DW_FORM_CLASS_REFERENCE;
1517
+ case DW_FORM_ref1: return DW_FORM_CLASS_REFERENCE;
1518
+ case DW_FORM_ref2: return DW_FORM_CLASS_REFERENCE;
1519
+ case DW_FORM_ref4: return DW_FORM_CLASS_REFERENCE;
1520
+ case DW_FORM_ref8: return DW_FORM_CLASS_REFERENCE;
1521
+ case DW_FORM_ref_udata: return DW_FORM_CLASS_REFERENCE;
1522
+ case DW_FORM_ref_sig8: return DW_FORM_CLASS_REFERENCE;
1523
+
1524
+ case DW_FORM_exprloc: return DW_FORM_CLASS_EXPRLOC;
1525
+
1526
+ case DW_FORM_flag: return DW_FORM_CLASS_FLAG;
1527
+ case DW_FORM_flag_present: return DW_FORM_CLASS_FLAG;
1528
+
1529
+ case DW_FORM_addrx: return DW_FORM_CLASS_ADDRESS; /* DWARF5 */
1530
+ case DW_FORM_GNU_addr_index: return DW_FORM_CLASS_ADDRESS;
1531
+ case DW_FORM_strx: return DW_FORM_CLASS_STRING; /* DWARF5 */
1532
+ case DW_FORM_GNU_str_index: return DW_FORM_CLASS_STRING;
1533
+
1534
+ case DW_FORM_GNU_ref_alt: return DW_FORM_CLASS_REFERENCE;
1535
+ case DW_FORM_GNU_strp_alt: return DW_FORM_CLASS_STRING;
1536
+ case DW_FORM_strp_sup: return DW_FORM_CLASS_STRING; /* DWARF5 */
1537
+
1538
+ case DW_FORM_indirect:
1539
+ default:
1540
+ break;
1541
+ };
1542
+ return DW_FORM_CLASS_UNKNOWN;
1543
+ };
1544
+
1545
+ /* Given a DIE, figure out what the CU's DWARF version is
1546
+ and the size of an offset
1547
+ and return it through the *version pointer and return
1548
+ DW_DLV_OK.
1549
+
1550
+ If we cannot find a CU,
1551
+ return DW_DLV_ERROR on error.
1552
+ In case of error no Dwarf_Debug was available,
1553
+ so setting a Dwarf_Error is somewhat futile.
1554
+ Never returns DW_DLV_NO_ENTRY.
1555
+ */
1556
+ int
1557
+ dwarf_get_version_of_die(Dwarf_Die die,
1558
+ Dwarf_Half *version,
1559
+ Dwarf_Half *offset_size)
1560
+ {
1561
+ Dwarf_CU_Context cucontext = 0;
1562
+ if (!die) {
1563
+ return DW_DLV_ERROR;
1564
+ }
1565
+ cucontext = die->di_cu_context;
1566
+ if (!cucontext) {
1567
+ return DW_DLV_ERROR;
1568
+ }
1569
+ *version = cucontext->cc_version_stamp;
1570
+ *offset_size = cucontext->cc_length_size;
1571
+ return DW_DLV_OK;
1572
+ }
1573
+
1574
+ Dwarf_Byte_Ptr
1575
+ _dwarf_calculate_section_end_ptr(Dwarf_CU_Context context)
1576
+ {
1577
+ Dwarf_Debug dbg = 0;
1578
+ Dwarf_Byte_Ptr info_end = 0;
1579
+ Dwarf_Byte_Ptr info_start = 0;
1580
+ Dwarf_Off off2 = 0;
1581
+ Dwarf_Small *dataptr = 0;
1582
+
1583
+ dbg = context->cc_dbg;
1584
+ dataptr = context->cc_is_info? dbg->de_debug_info.dss_data:
1585
+ dbg->de_debug_types.dss_data;
1586
+ off2 = context->cc_debug_offset;
1587
+ info_start = dataptr + off2;
1588
+ info_end = info_start + context->cc_length +
1589
+ context->cc_length_size +
1590
+ context->cc_extension_size;
1591
+ return info_end;
1592
+ }
1593
+
1594
+