pf2 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -2
  3. data/Cargo.lock +650 -0
  4. data/Cargo.toml +3 -0
  5. data/README.md +110 -13
  6. data/Rakefile +8 -0
  7. data/crates/backtrace-sys2/.gitignore +1 -0
  8. data/crates/backtrace-sys2/Cargo.toml +9 -0
  9. data/crates/backtrace-sys2/build.rs +48 -0
  10. data/crates/backtrace-sys2/src/lib.rs +5 -0
  11. data/crates/backtrace-sys2/src/libbacktrace/.gitignore +15 -0
  12. data/crates/backtrace-sys2/src/libbacktrace/Isaac.Newton-Opticks.txt +9286 -0
  13. data/crates/backtrace-sys2/src/libbacktrace/LICENSE +29 -0
  14. data/crates/backtrace-sys2/src/libbacktrace/Makefile.am +623 -0
  15. data/crates/backtrace-sys2/src/libbacktrace/Makefile.in +2666 -0
  16. data/crates/backtrace-sys2/src/libbacktrace/README.md +36 -0
  17. data/crates/backtrace-sys2/src/libbacktrace/aclocal.m4 +864 -0
  18. data/crates/backtrace-sys2/src/libbacktrace/alloc.c +167 -0
  19. data/crates/backtrace-sys2/src/libbacktrace/allocfail.c +136 -0
  20. data/crates/backtrace-sys2/src/libbacktrace/allocfail.sh +104 -0
  21. data/crates/backtrace-sys2/src/libbacktrace/atomic.c +113 -0
  22. data/crates/backtrace-sys2/src/libbacktrace/backtrace-supported.h.in +66 -0
  23. data/crates/backtrace-sys2/src/libbacktrace/backtrace.c +129 -0
  24. data/crates/backtrace-sys2/src/libbacktrace/backtrace.h +189 -0
  25. data/crates/backtrace-sys2/src/libbacktrace/btest.c +501 -0
  26. data/crates/backtrace-sys2/src/libbacktrace/compile +348 -0
  27. data/crates/backtrace-sys2/src/libbacktrace/config/enable.m4 +38 -0
  28. data/crates/backtrace-sys2/src/libbacktrace/config/lead-dot.m4 +31 -0
  29. data/crates/backtrace-sys2/src/libbacktrace/config/libtool.m4 +7436 -0
  30. data/crates/backtrace-sys2/src/libbacktrace/config/ltoptions.m4 +369 -0
  31. data/crates/backtrace-sys2/src/libbacktrace/config/ltsugar.m4 +123 -0
  32. data/crates/backtrace-sys2/src/libbacktrace/config/ltversion.m4 +23 -0
  33. data/crates/backtrace-sys2/src/libbacktrace/config/lt~obsolete.m4 +98 -0
  34. data/crates/backtrace-sys2/src/libbacktrace/config/multi.m4 +68 -0
  35. data/crates/backtrace-sys2/src/libbacktrace/config/override.m4 +117 -0
  36. data/crates/backtrace-sys2/src/libbacktrace/config/unwind_ipinfo.m4 +37 -0
  37. data/crates/backtrace-sys2/src/libbacktrace/config/warnings.m4 +227 -0
  38. data/crates/backtrace-sys2/src/libbacktrace/config.guess +1700 -0
  39. data/crates/backtrace-sys2/src/libbacktrace/config.h.in +182 -0
  40. data/crates/backtrace-sys2/src/libbacktrace/config.sub +1885 -0
  41. data/crates/backtrace-sys2/src/libbacktrace/configure +15740 -0
  42. data/crates/backtrace-sys2/src/libbacktrace/configure.ac +613 -0
  43. data/crates/backtrace-sys2/src/libbacktrace/dwarf.c +4402 -0
  44. data/crates/backtrace-sys2/src/libbacktrace/edtest.c +120 -0
  45. data/crates/backtrace-sys2/src/libbacktrace/edtest2.c +43 -0
  46. data/crates/backtrace-sys2/src/libbacktrace/elf.c +7443 -0
  47. data/crates/backtrace-sys2/src/libbacktrace/fileline.c +407 -0
  48. data/crates/backtrace-sys2/src/libbacktrace/filenames.h +52 -0
  49. data/crates/backtrace-sys2/src/libbacktrace/filetype.awk +13 -0
  50. data/crates/backtrace-sys2/src/libbacktrace/install-debuginfo-for-buildid.sh.in +65 -0
  51. data/crates/backtrace-sys2/src/libbacktrace/install-sh +501 -0
  52. data/crates/backtrace-sys2/src/libbacktrace/instrumented_alloc.c +114 -0
  53. data/crates/backtrace-sys2/src/libbacktrace/internal.h +389 -0
  54. data/crates/backtrace-sys2/src/libbacktrace/libtool.m4 +7436 -0
  55. data/crates/backtrace-sys2/src/libbacktrace/ltmain.sh +8636 -0
  56. data/crates/backtrace-sys2/src/libbacktrace/ltoptions.m4 +369 -0
  57. data/crates/backtrace-sys2/src/libbacktrace/ltsugar.m4 +123 -0
  58. data/crates/backtrace-sys2/src/libbacktrace/ltversion.m4 +23 -0
  59. data/crates/backtrace-sys2/src/libbacktrace/lt~obsolete.m4 +98 -0
  60. data/crates/backtrace-sys2/src/libbacktrace/macho.c +1355 -0
  61. data/crates/backtrace-sys2/src/libbacktrace/missing +215 -0
  62. data/crates/backtrace-sys2/src/libbacktrace/mmap.c +331 -0
  63. data/crates/backtrace-sys2/src/libbacktrace/mmapio.c +110 -0
  64. data/crates/backtrace-sys2/src/libbacktrace/move-if-change +83 -0
  65. data/crates/backtrace-sys2/src/libbacktrace/mtest.c +410 -0
  66. data/crates/backtrace-sys2/src/libbacktrace/nounwind.c +66 -0
  67. data/crates/backtrace-sys2/src/libbacktrace/pecoff.c +957 -0
  68. data/crates/backtrace-sys2/src/libbacktrace/posix.c +104 -0
  69. data/crates/backtrace-sys2/src/libbacktrace/print.c +92 -0
  70. data/crates/backtrace-sys2/src/libbacktrace/read.c +110 -0
  71. data/crates/backtrace-sys2/src/libbacktrace/simple.c +108 -0
  72. data/crates/backtrace-sys2/src/libbacktrace/sort.c +108 -0
  73. data/crates/backtrace-sys2/src/libbacktrace/state.c +72 -0
  74. data/crates/backtrace-sys2/src/libbacktrace/stest.c +137 -0
  75. data/crates/backtrace-sys2/src/libbacktrace/test-driver +148 -0
  76. data/crates/backtrace-sys2/src/libbacktrace/test_format.c +55 -0
  77. data/crates/backtrace-sys2/src/libbacktrace/testlib.c +234 -0
  78. data/crates/backtrace-sys2/src/libbacktrace/testlib.h +110 -0
  79. data/crates/backtrace-sys2/src/libbacktrace/ttest.c +161 -0
  80. data/crates/backtrace-sys2/src/libbacktrace/unittest.c +92 -0
  81. data/crates/backtrace-sys2/src/libbacktrace/unknown.c +65 -0
  82. data/crates/backtrace-sys2/src/libbacktrace/xcoff.c +1606 -0
  83. data/crates/backtrace-sys2/src/libbacktrace/xztest.c +508 -0
  84. data/crates/backtrace-sys2/src/libbacktrace/zstdtest.c +523 -0
  85. data/crates/backtrace-sys2/src/libbacktrace/ztest.c +541 -0
  86. data/ext/pf2/Cargo.toml +25 -0
  87. data/ext/pf2/build.rs +3 -0
  88. data/ext/pf2/extconf.rb +6 -1
  89. data/ext/pf2/src/backtrace.rs +126 -0
  90. data/ext/pf2/src/lib.rs +15 -0
  91. data/ext/pf2/src/profile.rs +65 -0
  92. data/ext/pf2/src/profile_serializer.rs +204 -0
  93. data/ext/pf2/src/ringbuffer.rs +152 -0
  94. data/ext/pf2/src/ruby_init.rs +74 -0
  95. data/ext/pf2/src/sample.rs +66 -0
  96. data/ext/pf2/src/siginfo_t.c +5 -0
  97. data/ext/pf2/src/signal_scheduler/configuration.rs +31 -0
  98. data/ext/pf2/src/signal_scheduler/timer_installer.rs +199 -0
  99. data/ext/pf2/src/signal_scheduler.rs +311 -0
  100. data/ext/pf2/src/timer_thread_scheduler.rs +319 -0
  101. data/ext/pf2/src/util.rs +30 -0
  102. data/lib/pf2/cli.rb +1 -1
  103. data/lib/pf2/reporter.rb +48 -16
  104. data/lib/pf2/version.rb +1 -1
  105. data/lib/pf2.rb +20 -5
  106. metadata +128 -5
  107. data/ext/pf2/pf2.c +0 -246
@@ -0,0 +1,4402 @@
1
+ /* dwarf.c -- Get file/line information from DWARF for backtraces.
2
+ Copyright (C) 2012-2021 Free Software Foundation, Inc.
3
+ Written by Ian Lance Taylor, Google.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are
7
+ met:
8
+
9
+ (1) Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions and the following disclaimer.
11
+
12
+ (2) Redistributions in binary form must reproduce the above copyright
13
+ notice, this list of conditions and the following disclaimer in
14
+ the documentation and/or other materials provided with the
15
+ distribution.
16
+
17
+ (3) The name of the author may not be used to
18
+ endorse or promote products derived from this software without
19
+ specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
+ POSSIBILITY OF SUCH DAMAGE. */
32
+
33
+ #include "config.h"
34
+
35
+ #include <errno.h>
36
+ #include <stdlib.h>
37
+ #include <string.h>
38
+ #include <sys/types.h>
39
+
40
+ #include "filenames.h"
41
+
42
+ #include "backtrace.h"
43
+ #include "internal.h"
44
+
45
+ /* DWARF constants. */
46
+
47
+ enum dwarf_tag {
48
+ DW_TAG_entry_point = 0x3,
49
+ DW_TAG_compile_unit = 0x11,
50
+ DW_TAG_inlined_subroutine = 0x1d,
51
+ DW_TAG_subprogram = 0x2e,
52
+ DW_TAG_skeleton_unit = 0x4a,
53
+ };
54
+
55
+ enum dwarf_form {
56
+ DW_FORM_addr = 0x01,
57
+ DW_FORM_block2 = 0x03,
58
+ DW_FORM_block4 = 0x04,
59
+ DW_FORM_data2 = 0x05,
60
+ DW_FORM_data4 = 0x06,
61
+ DW_FORM_data8 = 0x07,
62
+ DW_FORM_string = 0x08,
63
+ DW_FORM_block = 0x09,
64
+ DW_FORM_block1 = 0x0a,
65
+ DW_FORM_data1 = 0x0b,
66
+ DW_FORM_flag = 0x0c,
67
+ DW_FORM_sdata = 0x0d,
68
+ DW_FORM_strp = 0x0e,
69
+ DW_FORM_udata = 0x0f,
70
+ DW_FORM_ref_addr = 0x10,
71
+ DW_FORM_ref1 = 0x11,
72
+ DW_FORM_ref2 = 0x12,
73
+ DW_FORM_ref4 = 0x13,
74
+ DW_FORM_ref8 = 0x14,
75
+ DW_FORM_ref_udata = 0x15,
76
+ DW_FORM_indirect = 0x16,
77
+ DW_FORM_sec_offset = 0x17,
78
+ DW_FORM_exprloc = 0x18,
79
+ DW_FORM_flag_present = 0x19,
80
+ DW_FORM_ref_sig8 = 0x20,
81
+ DW_FORM_strx = 0x1a,
82
+ DW_FORM_addrx = 0x1b,
83
+ DW_FORM_ref_sup4 = 0x1c,
84
+ DW_FORM_strp_sup = 0x1d,
85
+ DW_FORM_data16 = 0x1e,
86
+ DW_FORM_line_strp = 0x1f,
87
+ DW_FORM_implicit_const = 0x21,
88
+ DW_FORM_loclistx = 0x22,
89
+ DW_FORM_rnglistx = 0x23,
90
+ DW_FORM_ref_sup8 = 0x24,
91
+ DW_FORM_strx1 = 0x25,
92
+ DW_FORM_strx2 = 0x26,
93
+ DW_FORM_strx3 = 0x27,
94
+ DW_FORM_strx4 = 0x28,
95
+ DW_FORM_addrx1 = 0x29,
96
+ DW_FORM_addrx2 = 0x2a,
97
+ DW_FORM_addrx3 = 0x2b,
98
+ DW_FORM_addrx4 = 0x2c,
99
+ DW_FORM_GNU_addr_index = 0x1f01,
100
+ DW_FORM_GNU_str_index = 0x1f02,
101
+ DW_FORM_GNU_ref_alt = 0x1f20,
102
+ DW_FORM_GNU_strp_alt = 0x1f21
103
+ };
104
+
105
+ enum dwarf_attribute {
106
+ DW_AT_sibling = 0x01,
107
+ DW_AT_location = 0x02,
108
+ DW_AT_name = 0x03,
109
+ DW_AT_ordering = 0x09,
110
+ DW_AT_subscr_data = 0x0a,
111
+ DW_AT_byte_size = 0x0b,
112
+ DW_AT_bit_offset = 0x0c,
113
+ DW_AT_bit_size = 0x0d,
114
+ DW_AT_element_list = 0x0f,
115
+ DW_AT_stmt_list = 0x10,
116
+ DW_AT_low_pc = 0x11,
117
+ DW_AT_high_pc = 0x12,
118
+ DW_AT_language = 0x13,
119
+ DW_AT_member = 0x14,
120
+ DW_AT_discr = 0x15,
121
+ DW_AT_discr_value = 0x16,
122
+ DW_AT_visibility = 0x17,
123
+ DW_AT_import = 0x18,
124
+ DW_AT_string_length = 0x19,
125
+ DW_AT_common_reference = 0x1a,
126
+ DW_AT_comp_dir = 0x1b,
127
+ DW_AT_const_value = 0x1c,
128
+ DW_AT_containing_type = 0x1d,
129
+ DW_AT_default_value = 0x1e,
130
+ DW_AT_inline = 0x20,
131
+ DW_AT_is_optional = 0x21,
132
+ DW_AT_lower_bound = 0x22,
133
+ DW_AT_producer = 0x25,
134
+ DW_AT_prototyped = 0x27,
135
+ DW_AT_return_addr = 0x2a,
136
+ DW_AT_start_scope = 0x2c,
137
+ DW_AT_bit_stride = 0x2e,
138
+ DW_AT_upper_bound = 0x2f,
139
+ DW_AT_abstract_origin = 0x31,
140
+ DW_AT_accessibility = 0x32,
141
+ DW_AT_address_class = 0x33,
142
+ DW_AT_artificial = 0x34,
143
+ DW_AT_base_types = 0x35,
144
+ DW_AT_calling_convention = 0x36,
145
+ DW_AT_count = 0x37,
146
+ DW_AT_data_member_location = 0x38,
147
+ DW_AT_decl_column = 0x39,
148
+ DW_AT_decl_file = 0x3a,
149
+ DW_AT_decl_line = 0x3b,
150
+ DW_AT_declaration = 0x3c,
151
+ DW_AT_discr_list = 0x3d,
152
+ DW_AT_encoding = 0x3e,
153
+ DW_AT_external = 0x3f,
154
+ DW_AT_frame_base = 0x40,
155
+ DW_AT_friend = 0x41,
156
+ DW_AT_identifier_case = 0x42,
157
+ DW_AT_macro_info = 0x43,
158
+ DW_AT_namelist_items = 0x44,
159
+ DW_AT_priority = 0x45,
160
+ DW_AT_segment = 0x46,
161
+ DW_AT_specification = 0x47,
162
+ DW_AT_static_link = 0x48,
163
+ DW_AT_type = 0x49,
164
+ DW_AT_use_location = 0x4a,
165
+ DW_AT_variable_parameter = 0x4b,
166
+ DW_AT_virtuality = 0x4c,
167
+ DW_AT_vtable_elem_location = 0x4d,
168
+ DW_AT_allocated = 0x4e,
169
+ DW_AT_associated = 0x4f,
170
+ DW_AT_data_location = 0x50,
171
+ DW_AT_byte_stride = 0x51,
172
+ DW_AT_entry_pc = 0x52,
173
+ DW_AT_use_UTF8 = 0x53,
174
+ DW_AT_extension = 0x54,
175
+ DW_AT_ranges = 0x55,
176
+ DW_AT_trampoline = 0x56,
177
+ DW_AT_call_column = 0x57,
178
+ DW_AT_call_file = 0x58,
179
+ DW_AT_call_line = 0x59,
180
+ DW_AT_description = 0x5a,
181
+ DW_AT_binary_scale = 0x5b,
182
+ DW_AT_decimal_scale = 0x5c,
183
+ DW_AT_small = 0x5d,
184
+ DW_AT_decimal_sign = 0x5e,
185
+ DW_AT_digit_count = 0x5f,
186
+ DW_AT_picture_string = 0x60,
187
+ DW_AT_mutable = 0x61,
188
+ DW_AT_threads_scaled = 0x62,
189
+ DW_AT_explicit = 0x63,
190
+ DW_AT_object_pointer = 0x64,
191
+ DW_AT_endianity = 0x65,
192
+ DW_AT_elemental = 0x66,
193
+ DW_AT_pure = 0x67,
194
+ DW_AT_recursive = 0x68,
195
+ DW_AT_signature = 0x69,
196
+ DW_AT_main_subprogram = 0x6a,
197
+ DW_AT_data_bit_offset = 0x6b,
198
+ DW_AT_const_expr = 0x6c,
199
+ DW_AT_enum_class = 0x6d,
200
+ DW_AT_linkage_name = 0x6e,
201
+ DW_AT_string_length_bit_size = 0x6f,
202
+ DW_AT_string_length_byte_size = 0x70,
203
+ DW_AT_rank = 0x71,
204
+ DW_AT_str_offsets_base = 0x72,
205
+ DW_AT_addr_base = 0x73,
206
+ DW_AT_rnglists_base = 0x74,
207
+ DW_AT_dwo_name = 0x76,
208
+ DW_AT_reference = 0x77,
209
+ DW_AT_rvalue_reference = 0x78,
210
+ DW_AT_macros = 0x79,
211
+ DW_AT_call_all_calls = 0x7a,
212
+ DW_AT_call_all_source_calls = 0x7b,
213
+ DW_AT_call_all_tail_calls = 0x7c,
214
+ DW_AT_call_return_pc = 0x7d,
215
+ DW_AT_call_value = 0x7e,
216
+ DW_AT_call_origin = 0x7f,
217
+ DW_AT_call_parameter = 0x80,
218
+ DW_AT_call_pc = 0x81,
219
+ DW_AT_call_tail_call = 0x82,
220
+ DW_AT_call_target = 0x83,
221
+ DW_AT_call_target_clobbered = 0x84,
222
+ DW_AT_call_data_location = 0x85,
223
+ DW_AT_call_data_value = 0x86,
224
+ DW_AT_noreturn = 0x87,
225
+ DW_AT_alignment = 0x88,
226
+ DW_AT_export_symbols = 0x89,
227
+ DW_AT_deleted = 0x8a,
228
+ DW_AT_defaulted = 0x8b,
229
+ DW_AT_loclists_base = 0x8c,
230
+ DW_AT_lo_user = 0x2000,
231
+ DW_AT_hi_user = 0x3fff,
232
+ DW_AT_MIPS_fde = 0x2001,
233
+ DW_AT_MIPS_loop_begin = 0x2002,
234
+ DW_AT_MIPS_tail_loop_begin = 0x2003,
235
+ DW_AT_MIPS_epilog_begin = 0x2004,
236
+ DW_AT_MIPS_loop_unroll_factor = 0x2005,
237
+ DW_AT_MIPS_software_pipeline_depth = 0x2006,
238
+ DW_AT_MIPS_linkage_name = 0x2007,
239
+ DW_AT_MIPS_stride = 0x2008,
240
+ DW_AT_MIPS_abstract_name = 0x2009,
241
+ DW_AT_MIPS_clone_origin = 0x200a,
242
+ DW_AT_MIPS_has_inlines = 0x200b,
243
+ DW_AT_HP_block_index = 0x2000,
244
+ DW_AT_HP_unmodifiable = 0x2001,
245
+ DW_AT_HP_prologue = 0x2005,
246
+ DW_AT_HP_epilogue = 0x2008,
247
+ DW_AT_HP_actuals_stmt_list = 0x2010,
248
+ DW_AT_HP_proc_per_section = 0x2011,
249
+ DW_AT_HP_raw_data_ptr = 0x2012,
250
+ DW_AT_HP_pass_by_reference = 0x2013,
251
+ DW_AT_HP_opt_level = 0x2014,
252
+ DW_AT_HP_prof_version_id = 0x2015,
253
+ DW_AT_HP_opt_flags = 0x2016,
254
+ DW_AT_HP_cold_region_low_pc = 0x2017,
255
+ DW_AT_HP_cold_region_high_pc = 0x2018,
256
+ DW_AT_HP_all_variables_modifiable = 0x2019,
257
+ DW_AT_HP_linkage_name = 0x201a,
258
+ DW_AT_HP_prof_flags = 0x201b,
259
+ DW_AT_HP_unit_name = 0x201f,
260
+ DW_AT_HP_unit_size = 0x2020,
261
+ DW_AT_HP_widened_byte_size = 0x2021,
262
+ DW_AT_HP_definition_points = 0x2022,
263
+ DW_AT_HP_default_location = 0x2023,
264
+ DW_AT_HP_is_result_param = 0x2029,
265
+ DW_AT_sf_names = 0x2101,
266
+ DW_AT_src_info = 0x2102,
267
+ DW_AT_mac_info = 0x2103,
268
+ DW_AT_src_coords = 0x2104,
269
+ DW_AT_body_begin = 0x2105,
270
+ DW_AT_body_end = 0x2106,
271
+ DW_AT_GNU_vector = 0x2107,
272
+ DW_AT_GNU_guarded_by = 0x2108,
273
+ DW_AT_GNU_pt_guarded_by = 0x2109,
274
+ DW_AT_GNU_guarded = 0x210a,
275
+ DW_AT_GNU_pt_guarded = 0x210b,
276
+ DW_AT_GNU_locks_excluded = 0x210c,
277
+ DW_AT_GNU_exclusive_locks_required = 0x210d,
278
+ DW_AT_GNU_shared_locks_required = 0x210e,
279
+ DW_AT_GNU_odr_signature = 0x210f,
280
+ DW_AT_GNU_template_name = 0x2110,
281
+ DW_AT_GNU_call_site_value = 0x2111,
282
+ DW_AT_GNU_call_site_data_value = 0x2112,
283
+ DW_AT_GNU_call_site_target = 0x2113,
284
+ DW_AT_GNU_call_site_target_clobbered = 0x2114,
285
+ DW_AT_GNU_tail_call = 0x2115,
286
+ DW_AT_GNU_all_tail_call_sites = 0x2116,
287
+ DW_AT_GNU_all_call_sites = 0x2117,
288
+ DW_AT_GNU_all_source_call_sites = 0x2118,
289
+ DW_AT_GNU_macros = 0x2119,
290
+ DW_AT_GNU_deleted = 0x211a,
291
+ DW_AT_GNU_dwo_name = 0x2130,
292
+ DW_AT_GNU_dwo_id = 0x2131,
293
+ DW_AT_GNU_ranges_base = 0x2132,
294
+ DW_AT_GNU_addr_base = 0x2133,
295
+ DW_AT_GNU_pubnames = 0x2134,
296
+ DW_AT_GNU_pubtypes = 0x2135,
297
+ DW_AT_GNU_discriminator = 0x2136,
298
+ DW_AT_GNU_locviews = 0x2137,
299
+ DW_AT_GNU_entry_view = 0x2138,
300
+ DW_AT_VMS_rtnbeg_pd_address = 0x2201,
301
+ DW_AT_use_GNAT_descriptive_type = 0x2301,
302
+ DW_AT_GNAT_descriptive_type = 0x2302,
303
+ DW_AT_GNU_numerator = 0x2303,
304
+ DW_AT_GNU_denominator = 0x2304,
305
+ DW_AT_GNU_bias = 0x2305,
306
+ DW_AT_upc_threads_scaled = 0x3210,
307
+ DW_AT_PGI_lbase = 0x3a00,
308
+ DW_AT_PGI_soffset = 0x3a01,
309
+ DW_AT_PGI_lstride = 0x3a02,
310
+ DW_AT_APPLE_optimized = 0x3fe1,
311
+ DW_AT_APPLE_flags = 0x3fe2,
312
+ DW_AT_APPLE_isa = 0x3fe3,
313
+ DW_AT_APPLE_block = 0x3fe4,
314
+ DW_AT_APPLE_major_runtime_vers = 0x3fe5,
315
+ DW_AT_APPLE_runtime_class = 0x3fe6,
316
+ DW_AT_APPLE_omit_frame_ptr = 0x3fe7,
317
+ DW_AT_APPLE_property_name = 0x3fe8,
318
+ DW_AT_APPLE_property_getter = 0x3fe9,
319
+ DW_AT_APPLE_property_setter = 0x3fea,
320
+ DW_AT_APPLE_property_attribute = 0x3feb,
321
+ DW_AT_APPLE_objc_complete_type = 0x3fec,
322
+ DW_AT_APPLE_property = 0x3fed
323
+ };
324
+
325
+ enum dwarf_line_number_op {
326
+ DW_LNS_extended_op = 0x0,
327
+ DW_LNS_copy = 0x1,
328
+ DW_LNS_advance_pc = 0x2,
329
+ DW_LNS_advance_line = 0x3,
330
+ DW_LNS_set_file = 0x4,
331
+ DW_LNS_set_column = 0x5,
332
+ DW_LNS_negate_stmt = 0x6,
333
+ DW_LNS_set_basic_block = 0x7,
334
+ DW_LNS_const_add_pc = 0x8,
335
+ DW_LNS_fixed_advance_pc = 0x9,
336
+ DW_LNS_set_prologue_end = 0xa,
337
+ DW_LNS_set_epilogue_begin = 0xb,
338
+ DW_LNS_set_isa = 0xc,
339
+ };
340
+
341
+ enum dwarf_extended_line_number_op {
342
+ DW_LNE_end_sequence = 0x1,
343
+ DW_LNE_set_address = 0x2,
344
+ DW_LNE_define_file = 0x3,
345
+ DW_LNE_set_discriminator = 0x4,
346
+ };
347
+
348
+ enum dwarf_line_number_content_type {
349
+ DW_LNCT_path = 0x1,
350
+ DW_LNCT_directory_index = 0x2,
351
+ DW_LNCT_timestamp = 0x3,
352
+ DW_LNCT_size = 0x4,
353
+ DW_LNCT_MD5 = 0x5,
354
+ DW_LNCT_lo_user = 0x2000,
355
+ DW_LNCT_hi_user = 0x3fff
356
+ };
357
+
358
+ enum dwarf_range_list_entry {
359
+ DW_RLE_end_of_list = 0x00,
360
+ DW_RLE_base_addressx = 0x01,
361
+ DW_RLE_startx_endx = 0x02,
362
+ DW_RLE_startx_length = 0x03,
363
+ DW_RLE_offset_pair = 0x04,
364
+ DW_RLE_base_address = 0x05,
365
+ DW_RLE_start_end = 0x06,
366
+ DW_RLE_start_length = 0x07
367
+ };
368
+
369
+ enum dwarf_unit_type {
370
+ DW_UT_compile = 0x01,
371
+ DW_UT_type = 0x02,
372
+ DW_UT_partial = 0x03,
373
+ DW_UT_skeleton = 0x04,
374
+ DW_UT_split_compile = 0x05,
375
+ DW_UT_split_type = 0x06,
376
+ DW_UT_lo_user = 0x80,
377
+ DW_UT_hi_user = 0xff
378
+ };
379
+
380
+ #if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN
381
+
382
+ /* If strnlen is not declared, provide our own version. */
383
+
384
+ static size_t
385
+ xstrnlen (const char *s, size_t maxlen)
386
+ {
387
+ size_t i;
388
+
389
+ for (i = 0; i < maxlen; ++i)
390
+ if (s[i] == '\0')
391
+ break;
392
+ return i;
393
+ }
394
+
395
+ #define strnlen xstrnlen
396
+
397
+ #endif
398
+
399
+ /* A buffer to read DWARF info. */
400
+
401
+ struct dwarf_buf
402
+ {
403
+ /* Buffer name for error messages. */
404
+ const char *name;
405
+ /* Start of the buffer. */
406
+ const unsigned char *start;
407
+ /* Next byte to read. */
408
+ const unsigned char *buf;
409
+ /* The number of bytes remaining. */
410
+ size_t left;
411
+ /* Whether the data is big-endian. */
412
+ int is_bigendian;
413
+ /* Error callback routine. */
414
+ backtrace_error_callback error_callback;
415
+ /* Data for error_callback. */
416
+ void *data;
417
+ /* Non-zero if we've reported an underflow error. */
418
+ int reported_underflow;
419
+ };
420
+
421
+ /* A single attribute in a DWARF abbreviation. */
422
+
423
+ struct attr
424
+ {
425
+ /* The attribute name. */
426
+ enum dwarf_attribute name;
427
+ /* The attribute form. */
428
+ enum dwarf_form form;
429
+ /* The attribute value, for DW_FORM_implicit_const. */
430
+ int64_t val;
431
+ };
432
+
433
+ /* A single DWARF abbreviation. */
434
+
435
+ struct abbrev
436
+ {
437
+ /* The abbrev code--the number used to refer to the abbrev. */
438
+ uint64_t code;
439
+ /* The entry tag. */
440
+ enum dwarf_tag tag;
441
+ /* Non-zero if this abbrev has child entries. */
442
+ int has_children;
443
+ /* The number of attributes. */
444
+ size_t num_attrs;
445
+ /* The attributes. */
446
+ struct attr *attrs;
447
+ };
448
+
449
+ /* The DWARF abbreviations for a compilation unit. This structure
450
+ only exists while reading the compilation unit. Most DWARF readers
451
+ seem to a hash table to map abbrev ID's to abbrev entries.
452
+ However, we primarily care about GCC, and GCC simply issues ID's in
453
+ numerical order starting at 1. So we simply keep a sorted vector,
454
+ and try to just look up the code. */
455
+
456
+ struct abbrevs
457
+ {
458
+ /* The number of abbrevs in the vector. */
459
+ size_t num_abbrevs;
460
+ /* The abbrevs, sorted by the code field. */
461
+ struct abbrev *abbrevs;
462
+ };
463
+
464
+ /* The different kinds of attribute values. */
465
+
466
+ enum attr_val_encoding
467
+ {
468
+ /* No attribute value. */
469
+ ATTR_VAL_NONE,
470
+ /* An address. */
471
+ ATTR_VAL_ADDRESS,
472
+ /* An index into the .debug_addr section, whose value is relative to
473
+ the DW_AT_addr_base attribute of the compilation unit. */
474
+ ATTR_VAL_ADDRESS_INDEX,
475
+ /* A unsigned integer. */
476
+ ATTR_VAL_UINT,
477
+ /* A sigd integer. */
478
+ ATTR_VAL_SINT,
479
+ /* A string. */
480
+ ATTR_VAL_STRING,
481
+ /* An index into the .debug_str_offsets section. */
482
+ ATTR_VAL_STRING_INDEX,
483
+ /* An offset to other data in the containing unit. */
484
+ ATTR_VAL_REF_UNIT,
485
+ /* An offset to other data within the .debug_info section. */
486
+ ATTR_VAL_REF_INFO,
487
+ /* An offset to other data within the alt .debug_info section. */
488
+ ATTR_VAL_REF_ALT_INFO,
489
+ /* An offset to data in some other section. */
490
+ ATTR_VAL_REF_SECTION,
491
+ /* A type signature. */
492
+ ATTR_VAL_REF_TYPE,
493
+ /* An index into the .debug_rnglists section. */
494
+ ATTR_VAL_RNGLISTS_INDEX,
495
+ /* A block of data (not represented). */
496
+ ATTR_VAL_BLOCK,
497
+ /* An expression (not represented). */
498
+ ATTR_VAL_EXPR,
499
+ };
500
+
501
+ /* An attribute value. */
502
+
503
+ struct attr_val
504
+ {
505
+ /* How the value is stored in the field u. */
506
+ enum attr_val_encoding encoding;
507
+ union
508
+ {
509
+ /* ATTR_VAL_ADDRESS*, ATTR_VAL_UINT, ATTR_VAL_REF*. */
510
+ uint64_t uint;
511
+ /* ATTR_VAL_SINT. */
512
+ int64_t sint;
513
+ /* ATTR_VAL_STRING. */
514
+ const char *string;
515
+ /* ATTR_VAL_BLOCK not stored. */
516
+ } u;
517
+ };
518
+
519
+ /* The line number program header. */
520
+
521
+ struct line_header
522
+ {
523
+ /* The version of the line number information. */
524
+ int version;
525
+ /* Address size. */
526
+ int addrsize;
527
+ /* The minimum instruction length. */
528
+ unsigned int min_insn_len;
529
+ /* The maximum number of ops per instruction. */
530
+ unsigned int max_ops_per_insn;
531
+ /* The line base for special opcodes. */
532
+ int line_base;
533
+ /* The line range for special opcodes. */
534
+ unsigned int line_range;
535
+ /* The opcode base--the first special opcode. */
536
+ unsigned int opcode_base;
537
+ /* Opcode lengths, indexed by opcode - 1. */
538
+ const unsigned char *opcode_lengths;
539
+ /* The number of directory entries. */
540
+ size_t dirs_count;
541
+ /* The directory entries. */
542
+ const char **dirs;
543
+ /* The number of filenames. */
544
+ size_t filenames_count;
545
+ /* The filenames. */
546
+ const char **filenames;
547
+ };
548
+
549
+ /* A format description from a line header. */
550
+
551
+ struct line_header_format
552
+ {
553
+ int lnct; /* LNCT code. */
554
+ enum dwarf_form form; /* Form of entry data. */
555
+ };
556
+
557
+ /* Map a single PC value to a file/line. We will keep a vector of
558
+ these sorted by PC value. Each file/line will be correct from the
559
+ PC up to the PC of the next entry if there is one. We allocate one
560
+ extra entry at the end so that we can use bsearch. */
561
+
562
+ struct line
563
+ {
564
+ /* PC. */
565
+ uintptr_t pc;
566
+ /* File name. Many entries in the array are expected to point to
567
+ the same file name. */
568
+ const char *filename;
569
+ /* Line number. */
570
+ int lineno;
571
+ /* Index of the object in the original array read from the DWARF
572
+ section, before it has been sorted. The index makes it possible
573
+ to use Quicksort and maintain stability. */
574
+ int idx;
575
+ };
576
+
577
+ /* A growable vector of line number information. This is used while
578
+ reading the line numbers. */
579
+
580
+ struct line_vector
581
+ {
582
+ /* Memory. This is an array of struct line. */
583
+ struct backtrace_vector vec;
584
+ /* Number of valid mappings. */
585
+ size_t count;
586
+ };
587
+
588
+ /* A function described in the debug info. */
589
+
590
+ struct function
591
+ {
592
+ /* The name of the function. */
593
+ const char *name;
594
+ /* If this is an inlined function, the filename of the call
595
+ site. */
596
+ const char *caller_filename;
597
+ /* If this is an inlined function, the line number of the call
598
+ site. */
599
+ int caller_lineno;
600
+ /* Map PC ranges to inlined functions. */
601
+ struct function_addrs *function_addrs;
602
+ size_t function_addrs_count;
603
+ };
604
+
605
+ /* An address range for a function. This maps a PC value to a
606
+ specific function. */
607
+
608
+ struct function_addrs
609
+ {
610
+ /* Range is LOW <= PC < HIGH. */
611
+ uintptr_t low;
612
+ uintptr_t high;
613
+ /* Function for this address range. */
614
+ struct function *function;
615
+ };
616
+
617
+ /* A growable vector of function address ranges. */
618
+
619
+ struct function_vector
620
+ {
621
+ /* Memory. This is an array of struct function_addrs. */
622
+ struct backtrace_vector vec;
623
+ /* Number of address ranges present. */
624
+ size_t count;
625
+ };
626
+
627
+ /* A DWARF compilation unit. This only holds the information we need
628
+ to map a PC to a file and line. */
629
+
630
+ struct unit
631
+ {
632
+ /* The first entry for this compilation unit. */
633
+ const unsigned char *unit_data;
634
+ /* The length of the data for this compilation unit. */
635
+ size_t unit_data_len;
636
+ /* The offset of UNIT_DATA from the start of the information for
637
+ this compilation unit. */
638
+ size_t unit_data_offset;
639
+ /* Offset of the start of the compilation unit from the start of the
640
+ .debug_info section. */
641
+ size_t low_offset;
642
+ /* Offset of the end of the compilation unit from the start of the
643
+ .debug_info section. */
644
+ size_t high_offset;
645
+ /* DWARF version. */
646
+ int version;
647
+ /* Whether unit is DWARF64. */
648
+ int is_dwarf64;
649
+ /* Address size. */
650
+ int addrsize;
651
+ /* Offset into line number information. */
652
+ off_t lineoff;
653
+ /* Offset of compilation unit in .debug_str_offsets. */
654
+ uint64_t str_offsets_base;
655
+ /* Offset of compilation unit in .debug_addr. */
656
+ uint64_t addr_base;
657
+ /* Offset of compilation unit in .debug_rnglists. */
658
+ uint64_t rnglists_base;
659
+ /* Primary source file. */
660
+ const char *filename;
661
+ /* Compilation command working directory. */
662
+ const char *comp_dir;
663
+ /* Absolute file name, only set if needed. */
664
+ const char *abs_filename;
665
+ /* The abbreviations for this unit. */
666
+ struct abbrevs abbrevs;
667
+
668
+ /* The fields above this point are read in during initialization and
669
+ may be accessed freely. The fields below this point are read in
670
+ as needed, and therefore require care, as different threads may
671
+ try to initialize them simultaneously. */
672
+
673
+ /* PC to line number mapping. This is NULL if the values have not
674
+ been read. This is (struct line *) -1 if there was an error
675
+ reading the values. */
676
+ struct line *lines;
677
+ /* Number of entries in lines. */
678
+ size_t lines_count;
679
+ /* PC ranges to function. */
680
+ struct function_addrs *function_addrs;
681
+ size_t function_addrs_count;
682
+ };
683
+
684
+ /* An address range for a compilation unit. This maps a PC value to a
685
+ specific compilation unit. Note that we invert the representation
686
+ in DWARF: instead of listing the units and attaching a list of
687
+ ranges, we list the ranges and have each one point to the unit.
688
+ This lets us do a binary search to find the unit. */
689
+
690
+ struct unit_addrs
691
+ {
692
+ /* Range is LOW <= PC < HIGH. */
693
+ uintptr_t low;
694
+ uintptr_t high;
695
+ /* Compilation unit for this address range. */
696
+ struct unit *u;
697
+ };
698
+
699
+ /* A growable vector of compilation unit address ranges. */
700
+
701
+ struct unit_addrs_vector
702
+ {
703
+ /* Memory. This is an array of struct unit_addrs. */
704
+ struct backtrace_vector vec;
705
+ /* Number of address ranges present. */
706
+ size_t count;
707
+ };
708
+
709
+ /* A growable vector of compilation unit pointer. */
710
+
711
+ struct unit_vector
712
+ {
713
+ struct backtrace_vector vec;
714
+ size_t count;
715
+ };
716
+
717
+ /* The information we need to map a PC to a file and line. */
718
+
719
+ struct dwarf_data
720
+ {
721
+ /* The data for the next file we know about. */
722
+ struct dwarf_data *next;
723
+ /* The data for .gnu_debugaltlink. */
724
+ struct dwarf_data *altlink;
725
+ /* The base address for this file. */
726
+ uintptr_t base_address;
727
+ /* A sorted list of address ranges. */
728
+ struct unit_addrs *addrs;
729
+ /* Number of address ranges in list. */
730
+ size_t addrs_count;
731
+ /* A sorted list of units. */
732
+ struct unit **units;
733
+ /* Number of units in the list. */
734
+ size_t units_count;
735
+ /* The unparsed DWARF debug data. */
736
+ struct dwarf_sections dwarf_sections;
737
+ /* Whether the data is big-endian or not. */
738
+ int is_bigendian;
739
+ /* A vector used for function addresses. We keep this here so that
740
+ we can grow the vector as we read more functions. */
741
+ struct function_vector fvec;
742
+ };
743
+
744
+ /* Report an error for a DWARF buffer. */
745
+
746
+ static void
747
+ dwarf_buf_error (struct dwarf_buf *buf, const char *msg, int errnum)
748
+ {
749
+ char b[200];
750
+
751
+ snprintf (b, sizeof b, "%s in %s at %d",
752
+ msg, buf->name, (int) (buf->buf - buf->start));
753
+ buf->error_callback (buf->data, b, errnum);
754
+ }
755
+
756
+ /* Require at least COUNT bytes in BUF. Return 1 if all is well, 0 on
757
+ error. */
758
+
759
+ static int
760
+ require (struct dwarf_buf *buf, size_t count)
761
+ {
762
+ if (buf->left >= count)
763
+ return 1;
764
+
765
+ if (!buf->reported_underflow)
766
+ {
767
+ dwarf_buf_error (buf, "DWARF underflow", 0);
768
+ buf->reported_underflow = 1;
769
+ }
770
+
771
+ return 0;
772
+ }
773
+
774
+ /* Advance COUNT bytes in BUF. Return 1 if all is well, 0 on
775
+ error. */
776
+
777
+ static int
778
+ advance (struct dwarf_buf *buf, size_t count)
779
+ {
780
+ if (!require (buf, count))
781
+ return 0;
782
+ buf->buf += count;
783
+ buf->left -= count;
784
+ return 1;
785
+ }
786
+
787
+ /* Read one zero-terminated string from BUF and advance past the string. */
788
+
789
+ static const char *
790
+ read_string (struct dwarf_buf *buf)
791
+ {
792
+ const char *p = (const char *)buf->buf;
793
+ size_t len = strnlen (p, buf->left);
794
+
795
+ /* - If len == left, we ran out of buffer before finding the zero terminator.
796
+ Generate an error by advancing len + 1.
797
+ - If len < left, advance by len + 1 to skip past the zero terminator. */
798
+ size_t count = len + 1;
799
+
800
+ if (!advance (buf, count))
801
+ return NULL;
802
+
803
+ return p;
804
+ }
805
+
806
+ /* Read one byte from BUF and advance 1 byte. */
807
+
808
+ static unsigned char
809
+ read_byte (struct dwarf_buf *buf)
810
+ {
811
+ const unsigned char *p = buf->buf;
812
+
813
+ if (!advance (buf, 1))
814
+ return 0;
815
+ return p[0];
816
+ }
817
+
818
+ /* Read a signed char from BUF and advance 1 byte. */
819
+
820
+ static signed char
821
+ read_sbyte (struct dwarf_buf *buf)
822
+ {
823
+ const unsigned char *p = buf->buf;
824
+
825
+ if (!advance (buf, 1))
826
+ return 0;
827
+ return (*p ^ 0x80) - 0x80;
828
+ }
829
+
830
+ /* Read a uint16 from BUF and advance 2 bytes. */
831
+
832
+ static uint16_t
833
+ read_uint16 (struct dwarf_buf *buf)
834
+ {
835
+ const unsigned char *p = buf->buf;
836
+
837
+ if (!advance (buf, 2))
838
+ return 0;
839
+ if (buf->is_bigendian)
840
+ return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
841
+ else
842
+ return ((uint16_t) p[1] << 8) | (uint16_t) p[0];
843
+ }
844
+
845
+ /* Read a 24 bit value from BUF and advance 3 bytes. */
846
+
847
+ static uint32_t
848
+ read_uint24 (struct dwarf_buf *buf)
849
+ {
850
+ const unsigned char *p = buf->buf;
851
+
852
+ if (!advance (buf, 3))
853
+ return 0;
854
+ if (buf->is_bigendian)
855
+ return (((uint32_t) p[0] << 16) | ((uint32_t) p[1] << 8)
856
+ | (uint32_t) p[2]);
857
+ else
858
+ return (((uint32_t) p[2] << 16) | ((uint32_t) p[1] << 8)
859
+ | (uint32_t) p[0]);
860
+ }
861
+
862
+ /* Read a uint32 from BUF and advance 4 bytes. */
863
+
864
+ static uint32_t
865
+ read_uint32 (struct dwarf_buf *buf)
866
+ {
867
+ const unsigned char *p = buf->buf;
868
+
869
+ if (!advance (buf, 4))
870
+ return 0;
871
+ if (buf->is_bigendian)
872
+ return (((uint32_t) p[0] << 24) | ((uint32_t) p[1] << 16)
873
+ | ((uint32_t) p[2] << 8) | (uint32_t) p[3]);
874
+ else
875
+ return (((uint32_t) p[3] << 24) | ((uint32_t) p[2] << 16)
876
+ | ((uint32_t) p[1] << 8) | (uint32_t) p[0]);
877
+ }
878
+
879
+ /* Read a uint64 from BUF and advance 8 bytes. */
880
+
881
+ static uint64_t
882
+ read_uint64 (struct dwarf_buf *buf)
883
+ {
884
+ const unsigned char *p = buf->buf;
885
+
886
+ if (!advance (buf, 8))
887
+ return 0;
888
+ if (buf->is_bigendian)
889
+ return (((uint64_t) p[0] << 56) | ((uint64_t) p[1] << 48)
890
+ | ((uint64_t) p[2] << 40) | ((uint64_t) p[3] << 32)
891
+ | ((uint64_t) p[4] << 24) | ((uint64_t) p[5] << 16)
892
+ | ((uint64_t) p[6] << 8) | (uint64_t) p[7]);
893
+ else
894
+ return (((uint64_t) p[7] << 56) | ((uint64_t) p[6] << 48)
895
+ | ((uint64_t) p[5] << 40) | ((uint64_t) p[4] << 32)
896
+ | ((uint64_t) p[3] << 24) | ((uint64_t) p[2] << 16)
897
+ | ((uint64_t) p[1] << 8) | (uint64_t) p[0]);
898
+ }
899
+
900
+ /* Read an offset from BUF and advance the appropriate number of
901
+ bytes. */
902
+
903
+ static uint64_t
904
+ read_offset (struct dwarf_buf *buf, int is_dwarf64)
905
+ {
906
+ if (is_dwarf64)
907
+ return read_uint64 (buf);
908
+ else
909
+ return read_uint32 (buf);
910
+ }
911
+
912
+ /* Read an address from BUF and advance the appropriate number of
913
+ bytes. */
914
+
915
+ static uint64_t
916
+ read_address (struct dwarf_buf *buf, int addrsize)
917
+ {
918
+ switch (addrsize)
919
+ {
920
+ case 1:
921
+ return read_byte (buf);
922
+ case 2:
923
+ return read_uint16 (buf);
924
+ case 4:
925
+ return read_uint32 (buf);
926
+ case 8:
927
+ return read_uint64 (buf);
928
+ default:
929
+ dwarf_buf_error (buf, "unrecognized address size", 0);
930
+ return 0;
931
+ }
932
+ }
933
+
934
+ /* Return whether a value is the highest possible address, given the
935
+ address size. */
936
+
937
+ static int
938
+ is_highest_address (uint64_t address, int addrsize)
939
+ {
940
+ switch (addrsize)
941
+ {
942
+ case 1:
943
+ return address == (unsigned char) -1;
944
+ case 2:
945
+ return address == (uint16_t) -1;
946
+ case 4:
947
+ return address == (uint32_t) -1;
948
+ case 8:
949
+ return address == (uint64_t) -1;
950
+ default:
951
+ return 0;
952
+ }
953
+ }
954
+
955
+ /* Read an unsigned LEB128 number. */
956
+
957
+ static uint64_t
958
+ read_uleb128 (struct dwarf_buf *buf)
959
+ {
960
+ uint64_t ret;
961
+ unsigned int shift;
962
+ int overflow;
963
+ unsigned char b;
964
+
965
+ ret = 0;
966
+ shift = 0;
967
+ overflow = 0;
968
+ do
969
+ {
970
+ const unsigned char *p;
971
+
972
+ p = buf->buf;
973
+ if (!advance (buf, 1))
974
+ return 0;
975
+ b = *p;
976
+ if (shift < 64)
977
+ ret |= ((uint64_t) (b & 0x7f)) << shift;
978
+ else if (!overflow)
979
+ {
980
+ dwarf_buf_error (buf, "LEB128 overflows uint64_t", 0);
981
+ overflow = 1;
982
+ }
983
+ shift += 7;
984
+ }
985
+ while ((b & 0x80) != 0);
986
+
987
+ return ret;
988
+ }
989
+
990
+ /* Read a signed LEB128 number. */
991
+
992
+ static int64_t
993
+ read_sleb128 (struct dwarf_buf *buf)
994
+ {
995
+ uint64_t val;
996
+ unsigned int shift;
997
+ int overflow;
998
+ unsigned char b;
999
+
1000
+ val = 0;
1001
+ shift = 0;
1002
+ overflow = 0;
1003
+ do
1004
+ {
1005
+ const unsigned char *p;
1006
+
1007
+ p = buf->buf;
1008
+ if (!advance (buf, 1))
1009
+ return 0;
1010
+ b = *p;
1011
+ if (shift < 64)
1012
+ val |= ((uint64_t) (b & 0x7f)) << shift;
1013
+ else if (!overflow)
1014
+ {
1015
+ dwarf_buf_error (buf, "signed LEB128 overflows uint64_t", 0);
1016
+ overflow = 1;
1017
+ }
1018
+ shift += 7;
1019
+ }
1020
+ while ((b & 0x80) != 0);
1021
+
1022
+ if ((b & 0x40) != 0 && shift < 64)
1023
+ val |= ((uint64_t) -1) << shift;
1024
+
1025
+ return (int64_t) val;
1026
+ }
1027
+
1028
+ /* Return the length of an LEB128 number. */
1029
+
1030
+ static size_t
1031
+ leb128_len (const unsigned char *p)
1032
+ {
1033
+ size_t ret;
1034
+
1035
+ ret = 1;
1036
+ while ((*p & 0x80) != 0)
1037
+ {
1038
+ ++p;
1039
+ ++ret;
1040
+ }
1041
+ return ret;
1042
+ }
1043
+
1044
+ /* Read initial_length from BUF and advance the appropriate number of bytes. */
1045
+
1046
+ static uint64_t
1047
+ read_initial_length (struct dwarf_buf *buf, int *is_dwarf64)
1048
+ {
1049
+ uint64_t len;
1050
+
1051
+ len = read_uint32 (buf);
1052
+ if (len == 0xffffffff)
1053
+ {
1054
+ len = read_uint64 (buf);
1055
+ *is_dwarf64 = 1;
1056
+ }
1057
+ else
1058
+ *is_dwarf64 = 0;
1059
+
1060
+ return len;
1061
+ }
1062
+
1063
+ /* Free an abbreviations structure. */
1064
+
1065
+ static void
1066
+ free_abbrevs (struct backtrace_state *state, struct abbrevs *abbrevs,
1067
+ backtrace_error_callback error_callback, void *data)
1068
+ {
1069
+ size_t i;
1070
+
1071
+ for (i = 0; i < abbrevs->num_abbrevs; ++i)
1072
+ backtrace_free (state, abbrevs->abbrevs[i].attrs,
1073
+ abbrevs->abbrevs[i].num_attrs * sizeof (struct attr),
1074
+ error_callback, data);
1075
+ backtrace_free (state, abbrevs->abbrevs,
1076
+ abbrevs->num_abbrevs * sizeof (struct abbrev),
1077
+ error_callback, data);
1078
+ abbrevs->num_abbrevs = 0;
1079
+ abbrevs->abbrevs = NULL;
1080
+ }
1081
+
1082
+ /* Read an attribute value. Returns 1 on success, 0 on failure. If
1083
+ the value can be represented as a uint64_t, sets *VAL and sets
1084
+ *IS_VALID to 1. We don't try to store the value of other attribute
1085
+ forms, because we don't care about them. */
1086
+
1087
+ static int
1088
+ read_attribute (enum dwarf_form form, uint64_t implicit_val,
1089
+ struct dwarf_buf *buf, int is_dwarf64, int version,
1090
+ int addrsize, const struct dwarf_sections *dwarf_sections,
1091
+ struct dwarf_data *altlink, struct attr_val *val)
1092
+ {
1093
+ /* Avoid warnings about val.u.FIELD may be used uninitialized if
1094
+ this function is inlined. The warnings aren't valid but can
1095
+ occur because the different fields are set and used
1096
+ conditionally. */
1097
+ memset (val, 0, sizeof *val);
1098
+
1099
+ switch (form)
1100
+ {
1101
+ case DW_FORM_addr:
1102
+ val->encoding = ATTR_VAL_ADDRESS;
1103
+ val->u.uint = read_address (buf, addrsize);
1104
+ return 1;
1105
+ case DW_FORM_block2:
1106
+ val->encoding = ATTR_VAL_BLOCK;
1107
+ return advance (buf, read_uint16 (buf));
1108
+ case DW_FORM_block4:
1109
+ val->encoding = ATTR_VAL_BLOCK;
1110
+ return advance (buf, read_uint32 (buf));
1111
+ case DW_FORM_data2:
1112
+ val->encoding = ATTR_VAL_UINT;
1113
+ val->u.uint = read_uint16 (buf);
1114
+ return 1;
1115
+ case DW_FORM_data4:
1116
+ val->encoding = ATTR_VAL_UINT;
1117
+ val->u.uint = read_uint32 (buf);
1118
+ return 1;
1119
+ case DW_FORM_data8:
1120
+ val->encoding = ATTR_VAL_UINT;
1121
+ val->u.uint = read_uint64 (buf);
1122
+ return 1;
1123
+ case DW_FORM_data16:
1124
+ val->encoding = ATTR_VAL_BLOCK;
1125
+ return advance (buf, 16);
1126
+ case DW_FORM_string:
1127
+ val->encoding = ATTR_VAL_STRING;
1128
+ val->u.string = read_string (buf);
1129
+ return val->u.string == NULL ? 0 : 1;
1130
+ case DW_FORM_block:
1131
+ val->encoding = ATTR_VAL_BLOCK;
1132
+ return advance (buf, read_uleb128 (buf));
1133
+ case DW_FORM_block1:
1134
+ val->encoding = ATTR_VAL_BLOCK;
1135
+ return advance (buf, read_byte (buf));
1136
+ case DW_FORM_data1:
1137
+ val->encoding = ATTR_VAL_UINT;
1138
+ val->u.uint = read_byte (buf);
1139
+ return 1;
1140
+ case DW_FORM_flag:
1141
+ val->encoding = ATTR_VAL_UINT;
1142
+ val->u.uint = read_byte (buf);
1143
+ return 1;
1144
+ case DW_FORM_sdata:
1145
+ val->encoding = ATTR_VAL_SINT;
1146
+ val->u.sint = read_sleb128 (buf);
1147
+ return 1;
1148
+ case DW_FORM_strp:
1149
+ {
1150
+ uint64_t offset;
1151
+
1152
+ offset = read_offset (buf, is_dwarf64);
1153
+ if (offset >= dwarf_sections->size[DEBUG_STR])
1154
+ {
1155
+ dwarf_buf_error (buf, "DW_FORM_strp out of range", 0);
1156
+ return 0;
1157
+ }
1158
+ val->encoding = ATTR_VAL_STRING;
1159
+ val->u.string =
1160
+ (const char *) dwarf_sections->data[DEBUG_STR] + offset;
1161
+ return 1;
1162
+ }
1163
+ case DW_FORM_line_strp:
1164
+ {
1165
+ uint64_t offset;
1166
+
1167
+ offset = read_offset (buf, is_dwarf64);
1168
+ if (offset >= dwarf_sections->size[DEBUG_LINE_STR])
1169
+ {
1170
+ dwarf_buf_error (buf, "DW_FORM_line_strp out of range", 0);
1171
+ return 0;
1172
+ }
1173
+ val->encoding = ATTR_VAL_STRING;
1174
+ val->u.string =
1175
+ (const char *) dwarf_sections->data[DEBUG_LINE_STR] + offset;
1176
+ return 1;
1177
+ }
1178
+ case DW_FORM_udata:
1179
+ val->encoding = ATTR_VAL_UINT;
1180
+ val->u.uint = read_uleb128 (buf);
1181
+ return 1;
1182
+ case DW_FORM_ref_addr:
1183
+ val->encoding = ATTR_VAL_REF_INFO;
1184
+ if (version == 2)
1185
+ val->u.uint = read_address (buf, addrsize);
1186
+ else
1187
+ val->u.uint = read_offset (buf, is_dwarf64);
1188
+ return 1;
1189
+ case DW_FORM_ref1:
1190
+ val->encoding = ATTR_VAL_REF_UNIT;
1191
+ val->u.uint = read_byte (buf);
1192
+ return 1;
1193
+ case DW_FORM_ref2:
1194
+ val->encoding = ATTR_VAL_REF_UNIT;
1195
+ val->u.uint = read_uint16 (buf);
1196
+ return 1;
1197
+ case DW_FORM_ref4:
1198
+ val->encoding = ATTR_VAL_REF_UNIT;
1199
+ val->u.uint = read_uint32 (buf);
1200
+ return 1;
1201
+ case DW_FORM_ref8:
1202
+ val->encoding = ATTR_VAL_REF_UNIT;
1203
+ val->u.uint = read_uint64 (buf);
1204
+ return 1;
1205
+ case DW_FORM_ref_udata:
1206
+ val->encoding = ATTR_VAL_REF_UNIT;
1207
+ val->u.uint = read_uleb128 (buf);
1208
+ return 1;
1209
+ case DW_FORM_indirect:
1210
+ {
1211
+ uint64_t form;
1212
+
1213
+ form = read_uleb128 (buf);
1214
+ if (form == DW_FORM_implicit_const)
1215
+ {
1216
+ dwarf_buf_error (buf,
1217
+ "DW_FORM_indirect to DW_FORM_implicit_const",
1218
+ 0);
1219
+ return 0;
1220
+ }
1221
+ return read_attribute ((enum dwarf_form) form, 0, buf, is_dwarf64,
1222
+ version, addrsize, dwarf_sections, altlink,
1223
+ val);
1224
+ }
1225
+ case DW_FORM_sec_offset:
1226
+ val->encoding = ATTR_VAL_REF_SECTION;
1227
+ val->u.uint = read_offset (buf, is_dwarf64);
1228
+ return 1;
1229
+ case DW_FORM_exprloc:
1230
+ val->encoding = ATTR_VAL_EXPR;
1231
+ return advance (buf, read_uleb128 (buf));
1232
+ case DW_FORM_flag_present:
1233
+ val->encoding = ATTR_VAL_UINT;
1234
+ val->u.uint = 1;
1235
+ return 1;
1236
+ case DW_FORM_ref_sig8:
1237
+ val->encoding = ATTR_VAL_REF_TYPE;
1238
+ val->u.uint = read_uint64 (buf);
1239
+ return 1;
1240
+ case DW_FORM_strx: case DW_FORM_strx1: case DW_FORM_strx2:
1241
+ case DW_FORM_strx3: case DW_FORM_strx4:
1242
+ {
1243
+ uint64_t offset;
1244
+
1245
+ switch (form)
1246
+ {
1247
+ case DW_FORM_strx:
1248
+ offset = read_uleb128 (buf);
1249
+ break;
1250
+ case DW_FORM_strx1:
1251
+ offset = read_byte (buf);
1252
+ break;
1253
+ case DW_FORM_strx2:
1254
+ offset = read_uint16 (buf);
1255
+ break;
1256
+ case DW_FORM_strx3:
1257
+ offset = read_uint24 (buf);
1258
+ break;
1259
+ case DW_FORM_strx4:
1260
+ offset = read_uint32 (buf);
1261
+ break;
1262
+ default:
1263
+ /* This case can't happen. */
1264
+ return 0;
1265
+ }
1266
+ val->encoding = ATTR_VAL_STRING_INDEX;
1267
+ val->u.uint = offset;
1268
+ return 1;
1269
+ }
1270
+ case DW_FORM_addrx: case DW_FORM_addrx1: case DW_FORM_addrx2:
1271
+ case DW_FORM_addrx3: case DW_FORM_addrx4:
1272
+ {
1273
+ uint64_t offset;
1274
+
1275
+ switch (form)
1276
+ {
1277
+ case DW_FORM_addrx:
1278
+ offset = read_uleb128 (buf);
1279
+ break;
1280
+ case DW_FORM_addrx1:
1281
+ offset = read_byte (buf);
1282
+ break;
1283
+ case DW_FORM_addrx2:
1284
+ offset = read_uint16 (buf);
1285
+ break;
1286
+ case DW_FORM_addrx3:
1287
+ offset = read_uint24 (buf);
1288
+ break;
1289
+ case DW_FORM_addrx4:
1290
+ offset = read_uint32 (buf);
1291
+ break;
1292
+ default:
1293
+ /* This case can't happen. */
1294
+ return 0;
1295
+ }
1296
+ val->encoding = ATTR_VAL_ADDRESS_INDEX;
1297
+ val->u.uint = offset;
1298
+ return 1;
1299
+ }
1300
+ case DW_FORM_ref_sup4:
1301
+ val->encoding = ATTR_VAL_REF_SECTION;
1302
+ val->u.uint = read_uint32 (buf);
1303
+ return 1;
1304
+ case DW_FORM_ref_sup8:
1305
+ val->encoding = ATTR_VAL_REF_SECTION;
1306
+ val->u.uint = read_uint64 (buf);
1307
+ return 1;
1308
+ case DW_FORM_implicit_const:
1309
+ val->encoding = ATTR_VAL_UINT;
1310
+ val->u.uint = implicit_val;
1311
+ return 1;
1312
+ case DW_FORM_loclistx:
1313
+ /* We don't distinguish this from DW_FORM_sec_offset. It
1314
+ * shouldn't matter since we don't care about loclists. */
1315
+ val->encoding = ATTR_VAL_REF_SECTION;
1316
+ val->u.uint = read_uleb128 (buf);
1317
+ return 1;
1318
+ case DW_FORM_rnglistx:
1319
+ val->encoding = ATTR_VAL_RNGLISTS_INDEX;
1320
+ val->u.uint = read_uleb128 (buf);
1321
+ return 1;
1322
+ case DW_FORM_GNU_addr_index:
1323
+ val->encoding = ATTR_VAL_REF_SECTION;
1324
+ val->u.uint = read_uleb128 (buf);
1325
+ return 1;
1326
+ case DW_FORM_GNU_str_index:
1327
+ val->encoding = ATTR_VAL_REF_SECTION;
1328
+ val->u.uint = read_uleb128 (buf);
1329
+ return 1;
1330
+ case DW_FORM_GNU_ref_alt:
1331
+ val->u.uint = read_offset (buf, is_dwarf64);
1332
+ if (altlink == NULL)
1333
+ {
1334
+ val->encoding = ATTR_VAL_NONE;
1335
+ return 1;
1336
+ }
1337
+ val->encoding = ATTR_VAL_REF_ALT_INFO;
1338
+ return 1;
1339
+ case DW_FORM_strp_sup: case DW_FORM_GNU_strp_alt:
1340
+ {
1341
+ uint64_t offset;
1342
+
1343
+ offset = read_offset (buf, is_dwarf64);
1344
+ if (altlink == NULL)
1345
+ {
1346
+ val->encoding = ATTR_VAL_NONE;
1347
+ return 1;
1348
+ }
1349
+ if (offset >= altlink->dwarf_sections.size[DEBUG_STR])
1350
+ {
1351
+ dwarf_buf_error (buf, "DW_FORM_strp_sup out of range", 0);
1352
+ return 0;
1353
+ }
1354
+ val->encoding = ATTR_VAL_STRING;
1355
+ val->u.string =
1356
+ (const char *) altlink->dwarf_sections.data[DEBUG_STR] + offset;
1357
+ return 1;
1358
+ }
1359
+ default:
1360
+ dwarf_buf_error (buf, "unrecognized DWARF form", -1);
1361
+ return 0;
1362
+ }
1363
+ }
1364
+
1365
+ /* If we can determine the value of a string attribute, set *STRING to
1366
+ point to the string. Return 1 on success, 0 on error. If we don't
1367
+ know the value, we consider that a success, and we don't change
1368
+ *STRING. An error is only reported for some sort of out of range
1369
+ offset. */
1370
+
1371
+ static int
1372
+ resolve_string (const struct dwarf_sections *dwarf_sections, int is_dwarf64,
1373
+ int is_bigendian, uint64_t str_offsets_base,
1374
+ const struct attr_val *val,
1375
+ backtrace_error_callback error_callback, void *data,
1376
+ const char **string)
1377
+ {
1378
+ switch (val->encoding)
1379
+ {
1380
+ case ATTR_VAL_STRING:
1381
+ *string = val->u.string;
1382
+ return 1;
1383
+
1384
+ case ATTR_VAL_STRING_INDEX:
1385
+ {
1386
+ uint64_t offset;
1387
+ struct dwarf_buf offset_buf;
1388
+
1389
+ offset = val->u.uint * (is_dwarf64 ? 8 : 4) + str_offsets_base;
1390
+ if (offset + (is_dwarf64 ? 8 : 4)
1391
+ > dwarf_sections->size[DEBUG_STR_OFFSETS])
1392
+ {
1393
+ error_callback (data, "DW_FORM_strx value out of range", 0);
1394
+ return 0;
1395
+ }
1396
+
1397
+ offset_buf.name = ".debug_str_offsets";
1398
+ offset_buf.start = dwarf_sections->data[DEBUG_STR_OFFSETS];
1399
+ offset_buf.buf = dwarf_sections->data[DEBUG_STR_OFFSETS] + offset;
1400
+ offset_buf.left = dwarf_sections->size[DEBUG_STR_OFFSETS] - offset;
1401
+ offset_buf.is_bigendian = is_bigendian;
1402
+ offset_buf.error_callback = error_callback;
1403
+ offset_buf.data = data;
1404
+ offset_buf.reported_underflow = 0;
1405
+
1406
+ offset = read_offset (&offset_buf, is_dwarf64);
1407
+ if (offset >= dwarf_sections->size[DEBUG_STR])
1408
+ {
1409
+ dwarf_buf_error (&offset_buf,
1410
+ "DW_FORM_strx offset out of range",
1411
+ 0);
1412
+ return 0;
1413
+ }
1414
+ *string = (const char *) dwarf_sections->data[DEBUG_STR] + offset;
1415
+ return 1;
1416
+ }
1417
+
1418
+ default:
1419
+ return 1;
1420
+ }
1421
+ }
1422
+
1423
+ /* Set *ADDRESS to the real address for a ATTR_VAL_ADDRESS_INDEX.
1424
+ Return 1 on success, 0 on error. */
1425
+
1426
+ static int
1427
+ resolve_addr_index (const struct dwarf_sections *dwarf_sections,
1428
+ uint64_t addr_base, int addrsize, int is_bigendian,
1429
+ uint64_t addr_index,
1430
+ backtrace_error_callback error_callback, void *data,
1431
+ uintptr_t *address)
1432
+ {
1433
+ uint64_t offset;
1434
+ struct dwarf_buf addr_buf;
1435
+
1436
+ offset = addr_index * addrsize + addr_base;
1437
+ if (offset + addrsize > dwarf_sections->size[DEBUG_ADDR])
1438
+ {
1439
+ error_callback (data, "DW_FORM_addrx value out of range", 0);
1440
+ return 0;
1441
+ }
1442
+
1443
+ addr_buf.name = ".debug_addr";
1444
+ addr_buf.start = dwarf_sections->data[DEBUG_ADDR];
1445
+ addr_buf.buf = dwarf_sections->data[DEBUG_ADDR] + offset;
1446
+ addr_buf.left = dwarf_sections->size[DEBUG_ADDR] - offset;
1447
+ addr_buf.is_bigendian = is_bigendian;
1448
+ addr_buf.error_callback = error_callback;
1449
+ addr_buf.data = data;
1450
+ addr_buf.reported_underflow = 0;
1451
+
1452
+ *address = (uintptr_t) read_address (&addr_buf, addrsize);
1453
+ return 1;
1454
+ }
1455
+
1456
+ /* Compare a unit offset against a unit for bsearch. */
1457
+
1458
+ static int
1459
+ units_search (const void *vkey, const void *ventry)
1460
+ {
1461
+ const size_t *key = (const size_t *) vkey;
1462
+ const struct unit *entry = *((const struct unit *const *) ventry);
1463
+ size_t offset;
1464
+
1465
+ offset = *key;
1466
+ if (offset < entry->low_offset)
1467
+ return -1;
1468
+ else if (offset >= entry->high_offset)
1469
+ return 1;
1470
+ else
1471
+ return 0;
1472
+ }
1473
+
1474
+ /* Find a unit in PU containing OFFSET. */
1475
+
1476
+ static struct unit *
1477
+ find_unit (struct unit **pu, size_t units_count, size_t offset)
1478
+ {
1479
+ struct unit **u;
1480
+ u = bsearch (&offset, pu, units_count, sizeof (struct unit *), units_search);
1481
+ return u == NULL ? NULL : *u;
1482
+ }
1483
+
1484
+ /* Compare function_addrs for qsort. When ranges are nested, make the
1485
+ smallest one sort last. */
1486
+
1487
+ static int
1488
+ function_addrs_compare (const void *v1, const void *v2)
1489
+ {
1490
+ const struct function_addrs *a1 = (const struct function_addrs *) v1;
1491
+ const struct function_addrs *a2 = (const struct function_addrs *) v2;
1492
+
1493
+ if (a1->low < a2->low)
1494
+ return -1;
1495
+ if (a1->low > a2->low)
1496
+ return 1;
1497
+ if (a1->high < a2->high)
1498
+ return 1;
1499
+ if (a1->high > a2->high)
1500
+ return -1;
1501
+ return strcmp (a1->function->name, a2->function->name);
1502
+ }
1503
+
1504
+ /* Compare a PC against a function_addrs for bsearch. We always
1505
+ allocate an entra entry at the end of the vector, so that this
1506
+ routine can safely look at the next entry. Note that if there are
1507
+ multiple ranges containing PC, which one will be returned is
1508
+ unpredictable. We compensate for that in dwarf_fileline. */
1509
+
1510
+ static int
1511
+ function_addrs_search (const void *vkey, const void *ventry)
1512
+ {
1513
+ const uintptr_t *key = (const uintptr_t *) vkey;
1514
+ const struct function_addrs *entry = (const struct function_addrs *) ventry;
1515
+ uintptr_t pc;
1516
+
1517
+ pc = *key;
1518
+ if (pc < entry->low)
1519
+ return -1;
1520
+ else if (pc > (entry + 1)->low)
1521
+ return 1;
1522
+ else
1523
+ return 0;
1524
+ }
1525
+
1526
+ /* Add a new compilation unit address range to a vector. This is
1527
+ called via add_ranges. Returns 1 on success, 0 on failure. */
1528
+
1529
+ static int
1530
+ add_unit_addr (struct backtrace_state *state, void *rdata,
1531
+ uintptr_t lowpc, uintptr_t highpc,
1532
+ backtrace_error_callback error_callback, void *data,
1533
+ void *pvec)
1534
+ {
1535
+ struct unit *u = (struct unit *) rdata;
1536
+ struct unit_addrs_vector *vec = (struct unit_addrs_vector *) pvec;
1537
+ struct unit_addrs *p;
1538
+
1539
+ /* Try to merge with the last entry. */
1540
+ if (vec->count > 0)
1541
+ {
1542
+ p = (struct unit_addrs *) vec->vec.base + (vec->count - 1);
1543
+ if ((lowpc == p->high || lowpc == p->high + 1)
1544
+ && u == p->u)
1545
+ {
1546
+ if (highpc > p->high)
1547
+ p->high = highpc;
1548
+ return 1;
1549
+ }
1550
+ }
1551
+
1552
+ p = ((struct unit_addrs *)
1553
+ backtrace_vector_grow (state, sizeof (struct unit_addrs),
1554
+ error_callback, data, &vec->vec));
1555
+ if (p == NULL)
1556
+ return 0;
1557
+
1558
+ p->low = lowpc;
1559
+ p->high = highpc;
1560
+ p->u = u;
1561
+
1562
+ ++vec->count;
1563
+
1564
+ return 1;
1565
+ }
1566
+
1567
+ /* Compare unit_addrs for qsort. When ranges are nested, make the
1568
+ smallest one sort last. */
1569
+
1570
+ static int
1571
+ unit_addrs_compare (const void *v1, const void *v2)
1572
+ {
1573
+ const struct unit_addrs *a1 = (const struct unit_addrs *) v1;
1574
+ const struct unit_addrs *a2 = (const struct unit_addrs *) v2;
1575
+
1576
+ if (a1->low < a2->low)
1577
+ return -1;
1578
+ if (a1->low > a2->low)
1579
+ return 1;
1580
+ if (a1->high < a2->high)
1581
+ return 1;
1582
+ if (a1->high > a2->high)
1583
+ return -1;
1584
+ if (a1->u->lineoff < a2->u->lineoff)
1585
+ return -1;
1586
+ if (a1->u->lineoff > a2->u->lineoff)
1587
+ return 1;
1588
+ return 0;
1589
+ }
1590
+
1591
+ /* Compare a PC against a unit_addrs for bsearch. We always allocate
1592
+ an entry entry at the end of the vector, so that this routine can
1593
+ safely look at the next entry. Note that if there are multiple
1594
+ ranges containing PC, which one will be returned is unpredictable.
1595
+ We compensate for that in dwarf_fileline. */
1596
+
1597
+ static int
1598
+ unit_addrs_search (const void *vkey, const void *ventry)
1599
+ {
1600
+ const uintptr_t *key = (const uintptr_t *) vkey;
1601
+ const struct unit_addrs *entry = (const struct unit_addrs *) ventry;
1602
+ uintptr_t pc;
1603
+
1604
+ pc = *key;
1605
+ if (pc < entry->low)
1606
+ return -1;
1607
+ else if (pc > (entry + 1)->low)
1608
+ return 1;
1609
+ else
1610
+ return 0;
1611
+ }
1612
+
1613
+ /* Sort the line vector by PC. We want a stable sort here to maintain
1614
+ the order of lines for the same PC values. Since the sequence is
1615
+ being sorted in place, their addresses cannot be relied on to
1616
+ maintain stability. That is the purpose of the index member. */
1617
+
1618
+ static int
1619
+ line_compare (const void *v1, const void *v2)
1620
+ {
1621
+ const struct line *ln1 = (const struct line *) v1;
1622
+ const struct line *ln2 = (const struct line *) v2;
1623
+
1624
+ if (ln1->pc < ln2->pc)
1625
+ return -1;
1626
+ else if (ln1->pc > ln2->pc)
1627
+ return 1;
1628
+ else if (ln1->idx < ln2->idx)
1629
+ return -1;
1630
+ else if (ln1->idx > ln2->idx)
1631
+ return 1;
1632
+ else
1633
+ return 0;
1634
+ }
1635
+
1636
+ /* Find a PC in a line vector. We always allocate an extra entry at
1637
+ the end of the lines vector, so that this routine can safely look
1638
+ at the next entry. Note that when there are multiple mappings for
1639
+ the same PC value, this will return the last one. */
1640
+
1641
+ static int
1642
+ line_search (const void *vkey, const void *ventry)
1643
+ {
1644
+ const uintptr_t *key = (const uintptr_t *) vkey;
1645
+ const struct line *entry = (const struct line *) ventry;
1646
+ uintptr_t pc;
1647
+
1648
+ pc = *key;
1649
+ if (pc < entry->pc)
1650
+ return -1;
1651
+ else if (pc >= (entry + 1)->pc)
1652
+ return 1;
1653
+ else
1654
+ return 0;
1655
+ }
1656
+
1657
+ /* Sort the abbrevs by the abbrev code. This function is passed to
1658
+ both qsort and bsearch. */
1659
+
1660
+ static int
1661
+ abbrev_compare (const void *v1, const void *v2)
1662
+ {
1663
+ const struct abbrev *a1 = (const struct abbrev *) v1;
1664
+ const struct abbrev *a2 = (const struct abbrev *) v2;
1665
+
1666
+ if (a1->code < a2->code)
1667
+ return -1;
1668
+ else if (a1->code > a2->code)
1669
+ return 1;
1670
+ else
1671
+ {
1672
+ /* This really shouldn't happen. It means there are two
1673
+ different abbrevs with the same code, and that means we don't
1674
+ know which one lookup_abbrev should return. */
1675
+ return 0;
1676
+ }
1677
+ }
1678
+
1679
+ /* Read the abbreviation table for a compilation unit. Returns 1 on
1680
+ success, 0 on failure. */
1681
+
1682
+ static int
1683
+ read_abbrevs (struct backtrace_state *state, uint64_t abbrev_offset,
1684
+ const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size,
1685
+ int is_bigendian, backtrace_error_callback error_callback,
1686
+ void *data, struct abbrevs *abbrevs)
1687
+ {
1688
+ struct dwarf_buf abbrev_buf;
1689
+ struct dwarf_buf count_buf;
1690
+ size_t num_abbrevs;
1691
+
1692
+ abbrevs->num_abbrevs = 0;
1693
+ abbrevs->abbrevs = NULL;
1694
+
1695
+ if (abbrev_offset >= dwarf_abbrev_size)
1696
+ {
1697
+ error_callback (data, "abbrev offset out of range", 0);
1698
+ return 0;
1699
+ }
1700
+
1701
+ abbrev_buf.name = ".debug_abbrev";
1702
+ abbrev_buf.start = dwarf_abbrev;
1703
+ abbrev_buf.buf = dwarf_abbrev + abbrev_offset;
1704
+ abbrev_buf.left = dwarf_abbrev_size - abbrev_offset;
1705
+ abbrev_buf.is_bigendian = is_bigendian;
1706
+ abbrev_buf.error_callback = error_callback;
1707
+ abbrev_buf.data = data;
1708
+ abbrev_buf.reported_underflow = 0;
1709
+
1710
+ /* Count the number of abbrevs in this list. */
1711
+
1712
+ count_buf = abbrev_buf;
1713
+ num_abbrevs = 0;
1714
+ while (read_uleb128 (&count_buf) != 0)
1715
+ {
1716
+ if (count_buf.reported_underflow)
1717
+ return 0;
1718
+ ++num_abbrevs;
1719
+ // Skip tag.
1720
+ read_uleb128 (&count_buf);
1721
+ // Skip has_children.
1722
+ read_byte (&count_buf);
1723
+ // Skip attributes.
1724
+ while (read_uleb128 (&count_buf) != 0)
1725
+ {
1726
+ uint64_t form;
1727
+
1728
+ form = read_uleb128 (&count_buf);
1729
+ if ((enum dwarf_form) form == DW_FORM_implicit_const)
1730
+ read_sleb128 (&count_buf);
1731
+ }
1732
+ // Skip form of last attribute.
1733
+ read_uleb128 (&count_buf);
1734
+ }
1735
+
1736
+ if (count_buf.reported_underflow)
1737
+ return 0;
1738
+
1739
+ if (num_abbrevs == 0)
1740
+ return 1;
1741
+
1742
+ abbrevs->abbrevs = ((struct abbrev *)
1743
+ backtrace_alloc (state,
1744
+ num_abbrevs * sizeof (struct abbrev),
1745
+ error_callback, data));
1746
+ if (abbrevs->abbrevs == NULL)
1747
+ return 0;
1748
+ abbrevs->num_abbrevs = num_abbrevs;
1749
+ memset (abbrevs->abbrevs, 0, num_abbrevs * sizeof (struct abbrev));
1750
+
1751
+ num_abbrevs = 0;
1752
+ while (1)
1753
+ {
1754
+ uint64_t code;
1755
+ struct abbrev a;
1756
+ size_t num_attrs;
1757
+ struct attr *attrs;
1758
+
1759
+ if (abbrev_buf.reported_underflow)
1760
+ goto fail;
1761
+
1762
+ code = read_uleb128 (&abbrev_buf);
1763
+ if (code == 0)
1764
+ break;
1765
+
1766
+ a.code = code;
1767
+ a.tag = (enum dwarf_tag) read_uleb128 (&abbrev_buf);
1768
+ a.has_children = read_byte (&abbrev_buf);
1769
+
1770
+ count_buf = abbrev_buf;
1771
+ num_attrs = 0;
1772
+ while (read_uleb128 (&count_buf) != 0)
1773
+ {
1774
+ uint64_t form;
1775
+
1776
+ ++num_attrs;
1777
+ form = read_uleb128 (&count_buf);
1778
+ if ((enum dwarf_form) form == DW_FORM_implicit_const)
1779
+ read_sleb128 (&count_buf);
1780
+ }
1781
+
1782
+ if (num_attrs == 0)
1783
+ {
1784
+ attrs = NULL;
1785
+ read_uleb128 (&abbrev_buf);
1786
+ read_uleb128 (&abbrev_buf);
1787
+ }
1788
+ else
1789
+ {
1790
+ attrs = ((struct attr *)
1791
+ backtrace_alloc (state, num_attrs * sizeof *attrs,
1792
+ error_callback, data));
1793
+ if (attrs == NULL)
1794
+ goto fail;
1795
+ num_attrs = 0;
1796
+ while (1)
1797
+ {
1798
+ uint64_t name;
1799
+ uint64_t form;
1800
+
1801
+ name = read_uleb128 (&abbrev_buf);
1802
+ form = read_uleb128 (&abbrev_buf);
1803
+ if (name == 0)
1804
+ break;
1805
+ attrs[num_attrs].name = (enum dwarf_attribute) name;
1806
+ attrs[num_attrs].form = (enum dwarf_form) form;
1807
+ if ((enum dwarf_form) form == DW_FORM_implicit_const)
1808
+ attrs[num_attrs].val = read_sleb128 (&abbrev_buf);
1809
+ else
1810
+ attrs[num_attrs].val = 0;
1811
+ ++num_attrs;
1812
+ }
1813
+ }
1814
+
1815
+ a.num_attrs = num_attrs;
1816
+ a.attrs = attrs;
1817
+
1818
+ abbrevs->abbrevs[num_abbrevs] = a;
1819
+ ++num_abbrevs;
1820
+ }
1821
+
1822
+ backtrace_qsort (abbrevs->abbrevs, abbrevs->num_abbrevs,
1823
+ sizeof (struct abbrev), abbrev_compare);
1824
+
1825
+ return 1;
1826
+
1827
+ fail:
1828
+ free_abbrevs (state, abbrevs, error_callback, data);
1829
+ return 0;
1830
+ }
1831
+
1832
+ /* Return the abbrev information for an abbrev code. */
1833
+
1834
+ static const struct abbrev *
1835
+ lookup_abbrev (struct abbrevs *abbrevs, uint64_t code,
1836
+ backtrace_error_callback error_callback, void *data)
1837
+ {
1838
+ struct abbrev key;
1839
+ void *p;
1840
+
1841
+ /* With GCC, where abbrevs are simply numbered in order, we should
1842
+ be able to just look up the entry. */
1843
+ if (code - 1 < abbrevs->num_abbrevs
1844
+ && abbrevs->abbrevs[code - 1].code == code)
1845
+ return &abbrevs->abbrevs[code - 1];
1846
+
1847
+ /* Otherwise we have to search. */
1848
+ memset (&key, 0, sizeof key);
1849
+ key.code = code;
1850
+ p = bsearch (&key, abbrevs->abbrevs, abbrevs->num_abbrevs,
1851
+ sizeof (struct abbrev), abbrev_compare);
1852
+ if (p == NULL)
1853
+ {
1854
+ error_callback (data, "invalid abbreviation code", 0);
1855
+ return NULL;
1856
+ }
1857
+ return (const struct abbrev *) p;
1858
+ }
1859
+
1860
+ /* This struct is used to gather address range information while
1861
+ reading attributes. We use this while building a mapping from
1862
+ address ranges to compilation units and then again while mapping
1863
+ from address ranges to function entries. Normally either
1864
+ lowpc/highpc is set or ranges is set. */
1865
+
1866
+ struct pcrange {
1867
+ uintptr_t lowpc; /* The low PC value. */
1868
+ int have_lowpc; /* Whether a low PC value was found. */
1869
+ int lowpc_is_addr_index; /* Whether lowpc is in .debug_addr. */
1870
+ uintptr_t highpc; /* The high PC value. */
1871
+ int have_highpc; /* Whether a high PC value was found. */
1872
+ int highpc_is_relative; /* Whether highpc is relative to lowpc. */
1873
+ int highpc_is_addr_index; /* Whether highpc is in .debug_addr. */
1874
+ uint64_t ranges; /* Offset in ranges section. */
1875
+ int have_ranges; /* Whether ranges is valid. */
1876
+ int ranges_is_index; /* Whether ranges is DW_FORM_rnglistx. */
1877
+ };
1878
+
1879
+ /* Update PCRANGE from an attribute value. */
1880
+
1881
+ static void
1882
+ update_pcrange (const struct attr* attr, const struct attr_val* val,
1883
+ struct pcrange *pcrange)
1884
+ {
1885
+ switch (attr->name)
1886
+ {
1887
+ case DW_AT_low_pc:
1888
+ if (val->encoding == ATTR_VAL_ADDRESS)
1889
+ {
1890
+ pcrange->lowpc = (uintptr_t) val->u.uint;
1891
+ pcrange->have_lowpc = 1;
1892
+ }
1893
+ else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
1894
+ {
1895
+ pcrange->lowpc = (uintptr_t) val->u.uint;
1896
+ pcrange->have_lowpc = 1;
1897
+ pcrange->lowpc_is_addr_index = 1;
1898
+ }
1899
+ break;
1900
+
1901
+ case DW_AT_high_pc:
1902
+ if (val->encoding == ATTR_VAL_ADDRESS)
1903
+ {
1904
+ pcrange->highpc = (uintptr_t) val->u.uint;
1905
+ pcrange->have_highpc = 1;
1906
+ }
1907
+ else if (val->encoding == ATTR_VAL_UINT)
1908
+ {
1909
+ pcrange->highpc = (uintptr_t) val->u.uint;
1910
+ pcrange->have_highpc = 1;
1911
+ pcrange->highpc_is_relative = 1;
1912
+ }
1913
+ else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
1914
+ {
1915
+ pcrange->highpc = (uintptr_t) val->u.uint;
1916
+ pcrange->have_highpc = 1;
1917
+ pcrange->highpc_is_addr_index = 1;
1918
+ }
1919
+ break;
1920
+
1921
+ case DW_AT_ranges:
1922
+ if (val->encoding == ATTR_VAL_UINT
1923
+ || val->encoding == ATTR_VAL_REF_SECTION)
1924
+ {
1925
+ pcrange->ranges = val->u.uint;
1926
+ pcrange->have_ranges = 1;
1927
+ }
1928
+ else if (val->encoding == ATTR_VAL_RNGLISTS_INDEX)
1929
+ {
1930
+ pcrange->ranges = val->u.uint;
1931
+ pcrange->have_ranges = 1;
1932
+ pcrange->ranges_is_index = 1;
1933
+ }
1934
+ break;
1935
+
1936
+ default:
1937
+ break;
1938
+ }
1939
+ }
1940
+
1941
+ /* Call ADD_RANGE for a low/high PC pair. Returns 1 on success, 0 on
1942
+ error. */
1943
+
1944
+ static int
1945
+ add_low_high_range (struct backtrace_state *state,
1946
+ const struct dwarf_sections *dwarf_sections,
1947
+ uintptr_t base_address, int is_bigendian,
1948
+ struct unit *u, const struct pcrange *pcrange,
1949
+ int (*add_range) (struct backtrace_state *state,
1950
+ void *rdata, uintptr_t lowpc,
1951
+ uintptr_t highpc,
1952
+ backtrace_error_callback error_callback,
1953
+ void *data, void *vec),
1954
+ void *rdata,
1955
+ backtrace_error_callback error_callback, void *data,
1956
+ void *vec)
1957
+ {
1958
+ uintptr_t lowpc;
1959
+ uintptr_t highpc;
1960
+
1961
+ lowpc = pcrange->lowpc;
1962
+ if (pcrange->lowpc_is_addr_index)
1963
+ {
1964
+ if (!resolve_addr_index (dwarf_sections, u->addr_base, u->addrsize,
1965
+ is_bigendian, lowpc, error_callback, data,
1966
+ &lowpc))
1967
+ return 0;
1968
+ }
1969
+
1970
+ highpc = pcrange->highpc;
1971
+ if (pcrange->highpc_is_addr_index)
1972
+ {
1973
+ if (!resolve_addr_index (dwarf_sections, u->addr_base, u->addrsize,
1974
+ is_bigendian, highpc, error_callback, data,
1975
+ &highpc))
1976
+ return 0;
1977
+ }
1978
+ if (pcrange->highpc_is_relative)
1979
+ highpc += lowpc;
1980
+
1981
+ /* Add in the base address of the module when recording PC values,
1982
+ so that we can look up the PC directly. */
1983
+ lowpc += base_address;
1984
+ highpc += base_address;
1985
+
1986
+ return add_range (state, rdata, lowpc, highpc, error_callback, data, vec);
1987
+ }
1988
+
1989
+ /* Call ADD_RANGE for each range read from .debug_ranges, as used in
1990
+ DWARF versions 2 through 4. */
1991
+
1992
+ static int
1993
+ add_ranges_from_ranges (
1994
+ struct backtrace_state *state,
1995
+ const struct dwarf_sections *dwarf_sections,
1996
+ uintptr_t base_address, int is_bigendian,
1997
+ struct unit *u, uintptr_t base,
1998
+ const struct pcrange *pcrange,
1999
+ int (*add_range) (struct backtrace_state *state, void *rdata,
2000
+ uintptr_t lowpc, uintptr_t highpc,
2001
+ backtrace_error_callback error_callback, void *data,
2002
+ void *vec),
2003
+ void *rdata,
2004
+ backtrace_error_callback error_callback, void *data,
2005
+ void *vec)
2006
+ {
2007
+ struct dwarf_buf ranges_buf;
2008
+
2009
+ if (pcrange->ranges >= dwarf_sections->size[DEBUG_RANGES])
2010
+ {
2011
+ error_callback (data, "ranges offset out of range", 0);
2012
+ return 0;
2013
+ }
2014
+
2015
+ ranges_buf.name = ".debug_ranges";
2016
+ ranges_buf.start = dwarf_sections->data[DEBUG_RANGES];
2017
+ ranges_buf.buf = dwarf_sections->data[DEBUG_RANGES] + pcrange->ranges;
2018
+ ranges_buf.left = dwarf_sections->size[DEBUG_RANGES] - pcrange->ranges;
2019
+ ranges_buf.is_bigendian = is_bigendian;
2020
+ ranges_buf.error_callback = error_callback;
2021
+ ranges_buf.data = data;
2022
+ ranges_buf.reported_underflow = 0;
2023
+
2024
+ while (1)
2025
+ {
2026
+ uint64_t low;
2027
+ uint64_t high;
2028
+
2029
+ if (ranges_buf.reported_underflow)
2030
+ return 0;
2031
+
2032
+ low = read_address (&ranges_buf, u->addrsize);
2033
+ high = read_address (&ranges_buf, u->addrsize);
2034
+
2035
+ if (low == 0 && high == 0)
2036
+ break;
2037
+
2038
+ if (is_highest_address (low, u->addrsize))
2039
+ base = (uintptr_t) high;
2040
+ else
2041
+ {
2042
+ if (!add_range (state, rdata,
2043
+ (uintptr_t) low + base + base_address,
2044
+ (uintptr_t) high + base + base_address,
2045
+ error_callback, data, vec))
2046
+ return 0;
2047
+ }
2048
+ }
2049
+
2050
+ if (ranges_buf.reported_underflow)
2051
+ return 0;
2052
+
2053
+ return 1;
2054
+ }
2055
+
2056
+ /* Call ADD_RANGE for each range read from .debug_rnglists, as used in
2057
+ DWARF version 5. */
2058
+
2059
+ static int
2060
+ add_ranges_from_rnglists (
2061
+ struct backtrace_state *state,
2062
+ const struct dwarf_sections *dwarf_sections,
2063
+ uintptr_t base_address, int is_bigendian,
2064
+ struct unit *u, uintptr_t base,
2065
+ const struct pcrange *pcrange,
2066
+ int (*add_range) (struct backtrace_state *state, void *rdata,
2067
+ uintptr_t lowpc, uintptr_t highpc,
2068
+ backtrace_error_callback error_callback, void *data,
2069
+ void *vec),
2070
+ void *rdata,
2071
+ backtrace_error_callback error_callback, void *data,
2072
+ void *vec)
2073
+ {
2074
+ uint64_t offset;
2075
+ struct dwarf_buf rnglists_buf;
2076
+
2077
+ if (!pcrange->ranges_is_index)
2078
+ offset = pcrange->ranges;
2079
+ else
2080
+ offset = u->rnglists_base + pcrange->ranges * (u->is_dwarf64 ? 8 : 4);
2081
+ if (offset >= dwarf_sections->size[DEBUG_RNGLISTS])
2082
+ {
2083
+ error_callback (data, "rnglists offset out of range", 0);
2084
+ return 0;
2085
+ }
2086
+
2087
+ rnglists_buf.name = ".debug_rnglists";
2088
+ rnglists_buf.start = dwarf_sections->data[DEBUG_RNGLISTS];
2089
+ rnglists_buf.buf = dwarf_sections->data[DEBUG_RNGLISTS] + offset;
2090
+ rnglists_buf.left = dwarf_sections->size[DEBUG_RNGLISTS] - offset;
2091
+ rnglists_buf.is_bigendian = is_bigendian;
2092
+ rnglists_buf.error_callback = error_callback;
2093
+ rnglists_buf.data = data;
2094
+ rnglists_buf.reported_underflow = 0;
2095
+
2096
+ if (pcrange->ranges_is_index)
2097
+ {
2098
+ offset = read_offset (&rnglists_buf, u->is_dwarf64);
2099
+ offset += u->rnglists_base;
2100
+ if (offset >= dwarf_sections->size[DEBUG_RNGLISTS])
2101
+ {
2102
+ error_callback (data, "rnglists index offset out of range", 0);
2103
+ return 0;
2104
+ }
2105
+ rnglists_buf.buf = dwarf_sections->data[DEBUG_RNGLISTS] + offset;
2106
+ rnglists_buf.left = dwarf_sections->size[DEBUG_RNGLISTS] - offset;
2107
+ }
2108
+
2109
+ while (1)
2110
+ {
2111
+ unsigned char rle;
2112
+
2113
+ rle = read_byte (&rnglists_buf);
2114
+ if (rle == DW_RLE_end_of_list)
2115
+ break;
2116
+ switch (rle)
2117
+ {
2118
+ case DW_RLE_base_addressx:
2119
+ {
2120
+ uint64_t index;
2121
+
2122
+ index = read_uleb128 (&rnglists_buf);
2123
+ if (!resolve_addr_index (dwarf_sections, u->addr_base,
2124
+ u->addrsize, is_bigendian, index,
2125
+ error_callback, data, &base))
2126
+ return 0;
2127
+ }
2128
+ break;
2129
+
2130
+ case DW_RLE_startx_endx:
2131
+ {
2132
+ uint64_t index;
2133
+ uintptr_t low;
2134
+ uintptr_t high;
2135
+
2136
+ index = read_uleb128 (&rnglists_buf);
2137
+ if (!resolve_addr_index (dwarf_sections, u->addr_base,
2138
+ u->addrsize, is_bigendian, index,
2139
+ error_callback, data, &low))
2140
+ return 0;
2141
+ index = read_uleb128 (&rnglists_buf);
2142
+ if (!resolve_addr_index (dwarf_sections, u->addr_base,
2143
+ u->addrsize, is_bigendian, index,
2144
+ error_callback, data, &high))
2145
+ return 0;
2146
+ if (!add_range (state, rdata, low + base_address,
2147
+ high + base_address, error_callback, data,
2148
+ vec))
2149
+ return 0;
2150
+ }
2151
+ break;
2152
+
2153
+ case DW_RLE_startx_length:
2154
+ {
2155
+ uint64_t index;
2156
+ uintptr_t low;
2157
+ uintptr_t length;
2158
+
2159
+ index = read_uleb128 (&rnglists_buf);
2160
+ if (!resolve_addr_index (dwarf_sections, u->addr_base,
2161
+ u->addrsize, is_bigendian, index,
2162
+ error_callback, data, &low))
2163
+ return 0;
2164
+ length = read_uleb128 (&rnglists_buf);
2165
+ low += base_address;
2166
+ if (!add_range (state, rdata, low, low + length,
2167
+ error_callback, data, vec))
2168
+ return 0;
2169
+ }
2170
+ break;
2171
+
2172
+ case DW_RLE_offset_pair:
2173
+ {
2174
+ uint64_t low;
2175
+ uint64_t high;
2176
+
2177
+ low = read_uleb128 (&rnglists_buf);
2178
+ high = read_uleb128 (&rnglists_buf);
2179
+ if (!add_range (state, rdata, low + base + base_address,
2180
+ high + base + base_address,
2181
+ error_callback, data, vec))
2182
+ return 0;
2183
+ }
2184
+ break;
2185
+
2186
+ case DW_RLE_base_address:
2187
+ base = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
2188
+ break;
2189
+
2190
+ case DW_RLE_start_end:
2191
+ {
2192
+ uintptr_t low;
2193
+ uintptr_t high;
2194
+
2195
+ low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
2196
+ high = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
2197
+ if (!add_range (state, rdata, low + base_address,
2198
+ high + base_address, error_callback, data,
2199
+ vec))
2200
+ return 0;
2201
+ }
2202
+ break;
2203
+
2204
+ case DW_RLE_start_length:
2205
+ {
2206
+ uintptr_t low;
2207
+ uintptr_t length;
2208
+
2209
+ low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
2210
+ length = (uintptr_t) read_uleb128 (&rnglists_buf);
2211
+ low += base_address;
2212
+ if (!add_range (state, rdata, low, low + length,
2213
+ error_callback, data, vec))
2214
+ return 0;
2215
+ }
2216
+ break;
2217
+
2218
+ default:
2219
+ dwarf_buf_error (&rnglists_buf, "unrecognized DW_RLE value", -1);
2220
+ return 0;
2221
+ }
2222
+ }
2223
+
2224
+ if (rnglists_buf.reported_underflow)
2225
+ return 0;
2226
+
2227
+ return 1;
2228
+ }
2229
+
2230
+ /* Call ADD_RANGE for each lowpc/highpc pair in PCRANGE. RDATA is
2231
+ passed to ADD_RANGE, and is either a struct unit * or a struct
2232
+ function *. VEC is the vector we are adding ranges to, and is
2233
+ either a struct unit_addrs_vector * or a struct function_vector *.
2234
+ Returns 1 on success, 0 on error. */
2235
+
2236
+ static int
2237
+ add_ranges (struct backtrace_state *state,
2238
+ const struct dwarf_sections *dwarf_sections,
2239
+ uintptr_t base_address, int is_bigendian,
2240
+ struct unit *u, uintptr_t base, const struct pcrange *pcrange,
2241
+ int (*add_range) (struct backtrace_state *state, void *rdata,
2242
+ uintptr_t lowpc, uintptr_t highpc,
2243
+ backtrace_error_callback error_callback,
2244
+ void *data, void *vec),
2245
+ void *rdata,
2246
+ backtrace_error_callback error_callback, void *data,
2247
+ void *vec)
2248
+ {
2249
+ if (pcrange->have_lowpc && pcrange->have_highpc)
2250
+ return add_low_high_range (state, dwarf_sections, base_address,
2251
+ is_bigendian, u, pcrange, add_range, rdata,
2252
+ error_callback, data, vec);
2253
+
2254
+ if (!pcrange->have_ranges)
2255
+ {
2256
+ /* Did not find any address ranges to add. */
2257
+ return 1;
2258
+ }
2259
+
2260
+ if (u->version < 5)
2261
+ return add_ranges_from_ranges (state, dwarf_sections, base_address,
2262
+ is_bigendian, u, base, pcrange, add_range,
2263
+ rdata, error_callback, data, vec);
2264
+ else
2265
+ return add_ranges_from_rnglists (state, dwarf_sections, base_address,
2266
+ is_bigendian, u, base, pcrange, add_range,
2267
+ rdata, error_callback, data, vec);
2268
+ }
2269
+
2270
+ /* Find the address range covered by a compilation unit, reading from
2271
+ UNIT_BUF and adding values to U. Returns 1 if all data could be
2272
+ read, 0 if there is some error. */
2273
+
2274
+ static int
2275
+ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
2276
+ struct dwarf_buf *unit_buf,
2277
+ const struct dwarf_sections *dwarf_sections,
2278
+ int is_bigendian, struct dwarf_data *altlink,
2279
+ backtrace_error_callback error_callback, void *data,
2280
+ struct unit *u, struct unit_addrs_vector *addrs,
2281
+ enum dwarf_tag *unit_tag)
2282
+ {
2283
+ while (unit_buf->left > 0)
2284
+ {
2285
+ uint64_t code;
2286
+ const struct abbrev *abbrev;
2287
+ struct pcrange pcrange;
2288
+ struct attr_val name_val;
2289
+ int have_name_val;
2290
+ struct attr_val comp_dir_val;
2291
+ int have_comp_dir_val;
2292
+ size_t i;
2293
+
2294
+ code = read_uleb128 (unit_buf);
2295
+ if (code == 0)
2296
+ return 1;
2297
+
2298
+ abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
2299
+ if (abbrev == NULL)
2300
+ return 0;
2301
+
2302
+ if (unit_tag != NULL)
2303
+ *unit_tag = abbrev->tag;
2304
+
2305
+ memset (&pcrange, 0, sizeof pcrange);
2306
+ memset (&name_val, 0, sizeof name_val);
2307
+ have_name_val = 0;
2308
+ memset (&comp_dir_val, 0, sizeof comp_dir_val);
2309
+ have_comp_dir_val = 0;
2310
+ for (i = 0; i < abbrev->num_attrs; ++i)
2311
+ {
2312
+ struct attr_val val;
2313
+
2314
+ if (!read_attribute (abbrev->attrs[i].form, abbrev->attrs[i].val,
2315
+ unit_buf, u->is_dwarf64, u->version,
2316
+ u->addrsize, dwarf_sections, altlink, &val))
2317
+ return 0;
2318
+
2319
+ switch (abbrev->attrs[i].name)
2320
+ {
2321
+ case DW_AT_low_pc: case DW_AT_high_pc: case DW_AT_ranges:
2322
+ update_pcrange (&abbrev->attrs[i], &val, &pcrange);
2323
+ break;
2324
+
2325
+ case DW_AT_stmt_list:
2326
+ if ((abbrev->tag == DW_TAG_compile_unit
2327
+ || abbrev->tag == DW_TAG_skeleton_unit)
2328
+ && (val.encoding == ATTR_VAL_UINT
2329
+ || val.encoding == ATTR_VAL_REF_SECTION))
2330
+ u->lineoff = val.u.uint;
2331
+ break;
2332
+
2333
+ case DW_AT_name:
2334
+ if (abbrev->tag == DW_TAG_compile_unit
2335
+ || abbrev->tag == DW_TAG_skeleton_unit)
2336
+ {
2337
+ name_val = val;
2338
+ have_name_val = 1;
2339
+ }
2340
+ break;
2341
+
2342
+ case DW_AT_comp_dir:
2343
+ if (abbrev->tag == DW_TAG_compile_unit
2344
+ || abbrev->tag == DW_TAG_skeleton_unit)
2345
+ {
2346
+ comp_dir_val = val;
2347
+ have_comp_dir_val = 1;
2348
+ }
2349
+ break;
2350
+
2351
+ case DW_AT_str_offsets_base:
2352
+ if ((abbrev->tag == DW_TAG_compile_unit
2353
+ || abbrev->tag == DW_TAG_skeleton_unit)
2354
+ && val.encoding == ATTR_VAL_REF_SECTION)
2355
+ u->str_offsets_base = val.u.uint;
2356
+ break;
2357
+
2358
+ case DW_AT_addr_base:
2359
+ if ((abbrev->tag == DW_TAG_compile_unit
2360
+ || abbrev->tag == DW_TAG_skeleton_unit)
2361
+ && val.encoding == ATTR_VAL_REF_SECTION)
2362
+ u->addr_base = val.u.uint;
2363
+ break;
2364
+
2365
+ case DW_AT_rnglists_base:
2366
+ if ((abbrev->tag == DW_TAG_compile_unit
2367
+ || abbrev->tag == DW_TAG_skeleton_unit)
2368
+ && val.encoding == ATTR_VAL_REF_SECTION)
2369
+ u->rnglists_base = val.u.uint;
2370
+ break;
2371
+
2372
+ default:
2373
+ break;
2374
+ }
2375
+ }
2376
+
2377
+ // Resolve strings after we're sure that we have seen
2378
+ // DW_AT_str_offsets_base.
2379
+ if (have_name_val)
2380
+ {
2381
+ if (!resolve_string (dwarf_sections, u->is_dwarf64, is_bigendian,
2382
+ u->str_offsets_base, &name_val,
2383
+ error_callback, data, &u->filename))
2384
+ return 0;
2385
+ }
2386
+ if (have_comp_dir_val)
2387
+ {
2388
+ if (!resolve_string (dwarf_sections, u->is_dwarf64, is_bigendian,
2389
+ u->str_offsets_base, &comp_dir_val,
2390
+ error_callback, data, &u->comp_dir))
2391
+ return 0;
2392
+ }
2393
+
2394
+ if (abbrev->tag == DW_TAG_compile_unit
2395
+ || abbrev->tag == DW_TAG_subprogram
2396
+ || abbrev->tag == DW_TAG_skeleton_unit)
2397
+ {
2398
+ if (!add_ranges (state, dwarf_sections, base_address,
2399
+ is_bigendian, u, pcrange.lowpc, &pcrange,
2400
+ add_unit_addr, (void *) u, error_callback, data,
2401
+ (void *) addrs))
2402
+ return 0;
2403
+
2404
+ /* If we found the PC range in the DW_TAG_compile_unit or
2405
+ DW_TAG_skeleton_unit, we can stop now. */
2406
+ if ((abbrev->tag == DW_TAG_compile_unit
2407
+ || abbrev->tag == DW_TAG_skeleton_unit)
2408
+ && (pcrange.have_ranges
2409
+ || (pcrange.have_lowpc && pcrange.have_highpc)))
2410
+ return 1;
2411
+ }
2412
+
2413
+ if (abbrev->has_children)
2414
+ {
2415
+ if (!find_address_ranges (state, base_address, unit_buf,
2416
+ dwarf_sections, is_bigendian, altlink,
2417
+ error_callback, data, u, addrs, NULL))
2418
+ return 0;
2419
+ }
2420
+ }
2421
+
2422
+ return 1;
2423
+ }
2424
+
2425
+ /* Build a mapping from address ranges to the compilation units where
2426
+ the line number information for that range can be found. Returns 1
2427
+ on success, 0 on failure. */
2428
+
2429
+ static int
2430
+ build_address_map (struct backtrace_state *state, uintptr_t base_address,
2431
+ const struct dwarf_sections *dwarf_sections,
2432
+ int is_bigendian, struct dwarf_data *altlink,
2433
+ backtrace_error_callback error_callback, void *data,
2434
+ struct unit_addrs_vector *addrs,
2435
+ struct unit_vector *unit_vec)
2436
+ {
2437
+ struct dwarf_buf info;
2438
+ struct backtrace_vector units;
2439
+ size_t units_count;
2440
+ size_t i;
2441
+ struct unit **pu;
2442
+ size_t unit_offset = 0;
2443
+ struct unit_addrs *pa;
2444
+
2445
+ memset (&addrs->vec, 0, sizeof addrs->vec);
2446
+ memset (&unit_vec->vec, 0, sizeof unit_vec->vec);
2447
+ addrs->count = 0;
2448
+ unit_vec->count = 0;
2449
+
2450
+ /* Read through the .debug_info section. FIXME: Should we use the
2451
+ .debug_aranges section? gdb and addr2line don't use it, but I'm
2452
+ not sure why. */
2453
+
2454
+ info.name = ".debug_info";
2455
+ info.start = dwarf_sections->data[DEBUG_INFO];
2456
+ info.buf = info.start;
2457
+ info.left = dwarf_sections->size[DEBUG_INFO];
2458
+ info.is_bigendian = is_bigendian;
2459
+ info.error_callback = error_callback;
2460
+ info.data = data;
2461
+ info.reported_underflow = 0;
2462
+
2463
+ memset (&units, 0, sizeof units);
2464
+ units_count = 0;
2465
+
2466
+ while (info.left > 0)
2467
+ {
2468
+ const unsigned char *unit_data_start;
2469
+ uint64_t len;
2470
+ int is_dwarf64;
2471
+ struct dwarf_buf unit_buf;
2472
+ int version;
2473
+ int unit_type;
2474
+ uint64_t abbrev_offset;
2475
+ int addrsize;
2476
+ struct unit *u;
2477
+ enum dwarf_tag unit_tag;
2478
+
2479
+ if (info.reported_underflow)
2480
+ goto fail;
2481
+
2482
+ unit_data_start = info.buf;
2483
+
2484
+ len = read_initial_length (&info, &is_dwarf64);
2485
+ unit_buf = info;
2486
+ unit_buf.left = len;
2487
+
2488
+ if (!advance (&info, len))
2489
+ goto fail;
2490
+
2491
+ version = read_uint16 (&unit_buf);
2492
+ if (version < 2 || version > 5)
2493
+ {
2494
+ dwarf_buf_error (&unit_buf, "unrecognized DWARF version", -1);
2495
+ goto fail;
2496
+ }
2497
+
2498
+ if (version < 5)
2499
+ unit_type = 0;
2500
+ else
2501
+ {
2502
+ unit_type = read_byte (&unit_buf);
2503
+ if (unit_type == DW_UT_type || unit_type == DW_UT_split_type)
2504
+ {
2505
+ /* This unit doesn't have anything we need. */
2506
+ continue;
2507
+ }
2508
+ }
2509
+
2510
+ pu = ((struct unit **)
2511
+ backtrace_vector_grow (state, sizeof (struct unit *),
2512
+ error_callback, data, &units));
2513
+ if (pu == NULL)
2514
+ goto fail;
2515
+
2516
+ u = ((struct unit *)
2517
+ backtrace_alloc (state, sizeof *u, error_callback, data));
2518
+ if (u == NULL)
2519
+ goto fail;
2520
+
2521
+ *pu = u;
2522
+ ++units_count;
2523
+
2524
+ if (version < 5)
2525
+ addrsize = 0; /* Set below. */
2526
+ else
2527
+ addrsize = read_byte (&unit_buf);
2528
+
2529
+ memset (&u->abbrevs, 0, sizeof u->abbrevs);
2530
+ abbrev_offset = read_offset (&unit_buf, is_dwarf64);
2531
+ if (!read_abbrevs (state, abbrev_offset,
2532
+ dwarf_sections->data[DEBUG_ABBREV],
2533
+ dwarf_sections->size[DEBUG_ABBREV],
2534
+ is_bigendian, error_callback, data, &u->abbrevs))
2535
+ goto fail;
2536
+
2537
+ if (version < 5)
2538
+ addrsize = read_byte (&unit_buf);
2539
+
2540
+ switch (unit_type)
2541
+ {
2542
+ case 0:
2543
+ break;
2544
+ case DW_UT_compile: case DW_UT_partial:
2545
+ break;
2546
+ case DW_UT_skeleton: case DW_UT_split_compile:
2547
+ read_uint64 (&unit_buf); /* dwo_id */
2548
+ break;
2549
+ default:
2550
+ break;
2551
+ }
2552
+
2553
+ u->low_offset = unit_offset;
2554
+ unit_offset += len + (is_dwarf64 ? 12 : 4);
2555
+ u->high_offset = unit_offset;
2556
+ u->unit_data = unit_buf.buf;
2557
+ u->unit_data_len = unit_buf.left;
2558
+ u->unit_data_offset = unit_buf.buf - unit_data_start;
2559
+ u->version = version;
2560
+ u->is_dwarf64 = is_dwarf64;
2561
+ u->addrsize = addrsize;
2562
+ u->filename = NULL;
2563
+ u->comp_dir = NULL;
2564
+ u->abs_filename = NULL;
2565
+ u->lineoff = 0;
2566
+ u->str_offsets_base = 0;
2567
+ u->addr_base = 0;
2568
+ u->rnglists_base = 0;
2569
+
2570
+ /* The actual line number mappings will be read as needed. */
2571
+ u->lines = NULL;
2572
+ u->lines_count = 0;
2573
+ u->function_addrs = NULL;
2574
+ u->function_addrs_count = 0;
2575
+
2576
+ if (!find_address_ranges (state, base_address, &unit_buf, dwarf_sections,
2577
+ is_bigendian, altlink, error_callback, data,
2578
+ u, addrs, &unit_tag))
2579
+ goto fail;
2580
+
2581
+ if (unit_buf.reported_underflow)
2582
+ goto fail;
2583
+ }
2584
+ if (info.reported_underflow)
2585
+ goto fail;
2586
+
2587
+ /* Add a trailing addrs entry, but don't include it in addrs->count. */
2588
+ pa = ((struct unit_addrs *)
2589
+ backtrace_vector_grow (state, sizeof (struct unit_addrs),
2590
+ error_callback, data, &addrs->vec));
2591
+ if (pa == NULL)
2592
+ goto fail;
2593
+ pa->low = 0;
2594
+ --pa->low;
2595
+ pa->high = pa->low;
2596
+ pa->u = NULL;
2597
+
2598
+ unit_vec->vec = units;
2599
+ unit_vec->count = units_count;
2600
+ return 1;
2601
+
2602
+ fail:
2603
+ if (units_count > 0)
2604
+ {
2605
+ pu = (struct unit **) units.base;
2606
+ for (i = 0; i < units_count; i++)
2607
+ {
2608
+ free_abbrevs (state, &pu[i]->abbrevs, error_callback, data);
2609
+ backtrace_free (state, pu[i], sizeof **pu, error_callback, data);
2610
+ }
2611
+ backtrace_vector_free (state, &units, error_callback, data);
2612
+ }
2613
+ if (addrs->count > 0)
2614
+ {
2615
+ backtrace_vector_free (state, &addrs->vec, error_callback, data);
2616
+ addrs->count = 0;
2617
+ }
2618
+ return 0;
2619
+ }
2620
+
2621
+ /* Add a new mapping to the vector of line mappings that we are
2622
+ building. Returns 1 on success, 0 on failure. */
2623
+
2624
+ static int
2625
+ add_line (struct backtrace_state *state, struct dwarf_data *ddata,
2626
+ uintptr_t pc, const char *filename, int lineno,
2627
+ backtrace_error_callback error_callback, void *data,
2628
+ struct line_vector *vec)
2629
+ {
2630
+ struct line *ln;
2631
+
2632
+ /* If we are adding the same mapping, ignore it. This can happen
2633
+ when using discriminators. */
2634
+ if (vec->count > 0)
2635
+ {
2636
+ ln = (struct line *) vec->vec.base + (vec->count - 1);
2637
+ if (pc == ln->pc && filename == ln->filename && lineno == ln->lineno)
2638
+ return 1;
2639
+ }
2640
+
2641
+ ln = ((struct line *)
2642
+ backtrace_vector_grow (state, sizeof (struct line), error_callback,
2643
+ data, &vec->vec));
2644
+ if (ln == NULL)
2645
+ return 0;
2646
+
2647
+ /* Add in the base address here, so that we can look up the PC
2648
+ directly. */
2649
+ ln->pc = pc + ddata->base_address;
2650
+
2651
+ ln->filename = filename;
2652
+ ln->lineno = lineno;
2653
+ ln->idx = vec->count;
2654
+
2655
+ ++vec->count;
2656
+
2657
+ return 1;
2658
+ }
2659
+
2660
+ /* Free the line header information. */
2661
+
2662
+ static void
2663
+ free_line_header (struct backtrace_state *state, struct line_header *hdr,
2664
+ backtrace_error_callback error_callback, void *data)
2665
+ {
2666
+ if (hdr->dirs_count != 0)
2667
+ backtrace_free (state, hdr->dirs, hdr->dirs_count * sizeof (const char *),
2668
+ error_callback, data);
2669
+ backtrace_free (state, hdr->filenames,
2670
+ hdr->filenames_count * sizeof (char *),
2671
+ error_callback, data);
2672
+ }
2673
+
2674
+ /* Read the directories and file names for a line header for version
2675
+ 2, setting fields in HDR. Return 1 on success, 0 on failure. */
2676
+
2677
+ static int
2678
+ read_v2_paths (struct backtrace_state *state, struct unit *u,
2679
+ struct dwarf_buf *hdr_buf, struct line_header *hdr)
2680
+ {
2681
+ const unsigned char *p;
2682
+ const unsigned char *pend;
2683
+ size_t i;
2684
+
2685
+ /* Count the number of directory entries. */
2686
+ hdr->dirs_count = 0;
2687
+ p = hdr_buf->buf;
2688
+ pend = p + hdr_buf->left;
2689
+ while (p < pend && *p != '\0')
2690
+ {
2691
+ p += strnlen((const char *) p, pend - p) + 1;
2692
+ ++hdr->dirs_count;
2693
+ }
2694
+
2695
+ /* The index of the first entry in the list of directories is 1. Index 0 is
2696
+ used for the current directory of the compilation. To simplify index
2697
+ handling, we set entry 0 to the compilation unit directory. */
2698
+ ++hdr->dirs_count;
2699
+ hdr->dirs = ((const char **)
2700
+ backtrace_alloc (state,
2701
+ hdr->dirs_count * sizeof (const char *),
2702
+ hdr_buf->error_callback,
2703
+ hdr_buf->data));
2704
+ if (hdr->dirs == NULL)
2705
+ return 0;
2706
+
2707
+ hdr->dirs[0] = u->comp_dir;
2708
+ i = 1;
2709
+ while (*hdr_buf->buf != '\0')
2710
+ {
2711
+ if (hdr_buf->reported_underflow)
2712
+ return 0;
2713
+
2714
+ hdr->dirs[i] = read_string (hdr_buf);
2715
+ if (hdr->dirs[i] == NULL)
2716
+ return 0;
2717
+ ++i;
2718
+ }
2719
+ if (!advance (hdr_buf, 1))
2720
+ return 0;
2721
+
2722
+ /* Count the number of file entries. */
2723
+ hdr->filenames_count = 0;
2724
+ p = hdr_buf->buf;
2725
+ pend = p + hdr_buf->left;
2726
+ while (p < pend && *p != '\0')
2727
+ {
2728
+ p += strnlen ((const char *) p, pend - p) + 1;
2729
+ p += leb128_len (p);
2730
+ p += leb128_len (p);
2731
+ p += leb128_len (p);
2732
+ ++hdr->filenames_count;
2733
+ }
2734
+
2735
+ /* The index of the first entry in the list of file names is 1. Index 0 is
2736
+ used for the DW_AT_name of the compilation unit. To simplify index
2737
+ handling, we set entry 0 to the compilation unit file name. */
2738
+ ++hdr->filenames_count;
2739
+ hdr->filenames = ((const char **)
2740
+ backtrace_alloc (state,
2741
+ hdr->filenames_count * sizeof (char *),
2742
+ hdr_buf->error_callback,
2743
+ hdr_buf->data));
2744
+ if (hdr->filenames == NULL)
2745
+ return 0;
2746
+ hdr->filenames[0] = u->filename;
2747
+ i = 1;
2748
+ while (*hdr_buf->buf != '\0')
2749
+ {
2750
+ const char *filename;
2751
+ uint64_t dir_index;
2752
+
2753
+ if (hdr_buf->reported_underflow)
2754
+ return 0;
2755
+
2756
+ filename = read_string (hdr_buf);
2757
+ if (filename == NULL)
2758
+ return 0;
2759
+ dir_index = read_uleb128 (hdr_buf);
2760
+ if (IS_ABSOLUTE_PATH (filename)
2761
+ || (dir_index < hdr->dirs_count && hdr->dirs[dir_index] == NULL))
2762
+ hdr->filenames[i] = filename;
2763
+ else
2764
+ {
2765
+ const char *dir;
2766
+ size_t dir_len;
2767
+ size_t filename_len;
2768
+ char *s;
2769
+
2770
+ if (dir_index < hdr->dirs_count)
2771
+ dir = hdr->dirs[dir_index];
2772
+ else
2773
+ {
2774
+ dwarf_buf_error (hdr_buf,
2775
+ ("invalid directory index in "
2776
+ "line number program header"),
2777
+ 0);
2778
+ return 0;
2779
+ }
2780
+ dir_len = strlen (dir);
2781
+ filename_len = strlen (filename);
2782
+ s = ((char *) backtrace_alloc (state, dir_len + filename_len + 2,
2783
+ hdr_buf->error_callback,
2784
+ hdr_buf->data));
2785
+ if (s == NULL)
2786
+ return 0;
2787
+ memcpy (s, dir, dir_len);
2788
+ /* FIXME: If we are on a DOS-based file system, and the
2789
+ directory or the file name use backslashes, then we
2790
+ should use a backslash here. */
2791
+ s[dir_len] = '/';
2792
+ memcpy (s + dir_len + 1, filename, filename_len + 1);
2793
+ hdr->filenames[i] = s;
2794
+ }
2795
+
2796
+ /* Ignore the modification time and size. */
2797
+ read_uleb128 (hdr_buf);
2798
+ read_uleb128 (hdr_buf);
2799
+
2800
+ ++i;
2801
+ }
2802
+
2803
+ return 1;
2804
+ }
2805
+
2806
+ /* Read a single version 5 LNCT entry for a directory or file name in a
2807
+ line header. Sets *STRING to the resulting name, ignoring other
2808
+ data. Return 1 on success, 0 on failure. */
2809
+
2810
+ static int
2811
+ read_lnct (struct backtrace_state *state, struct dwarf_data *ddata,
2812
+ struct unit *u, struct dwarf_buf *hdr_buf,
2813
+ const struct line_header *hdr, size_t formats_count,
2814
+ const struct line_header_format *formats, const char **string)
2815
+ {
2816
+ size_t i;
2817
+ const char *dir;
2818
+ const char *path;
2819
+
2820
+ dir = NULL;
2821
+ path = NULL;
2822
+ for (i = 0; i < formats_count; i++)
2823
+ {
2824
+ struct attr_val val;
2825
+
2826
+ if (!read_attribute (formats[i].form, 0, hdr_buf, u->is_dwarf64,
2827
+ u->version, hdr->addrsize, &ddata->dwarf_sections,
2828
+ ddata->altlink, &val))
2829
+ return 0;
2830
+ switch (formats[i].lnct)
2831
+ {
2832
+ case DW_LNCT_path:
2833
+ if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
2834
+ ddata->is_bigendian, u->str_offsets_base,
2835
+ &val, hdr_buf->error_callback, hdr_buf->data,
2836
+ &path))
2837
+ return 0;
2838
+ break;
2839
+ case DW_LNCT_directory_index:
2840
+ if (val.encoding == ATTR_VAL_UINT)
2841
+ {
2842
+ if (val.u.uint >= hdr->dirs_count)
2843
+ {
2844
+ dwarf_buf_error (hdr_buf,
2845
+ ("invalid directory index in "
2846
+ "line number program header"),
2847
+ 0);
2848
+ return 0;
2849
+ }
2850
+ dir = hdr->dirs[val.u.uint];
2851
+ }
2852
+ break;
2853
+ default:
2854
+ /* We don't care about timestamps or sizes or hashes. */
2855
+ break;
2856
+ }
2857
+ }
2858
+
2859
+ if (path == NULL)
2860
+ {
2861
+ dwarf_buf_error (hdr_buf,
2862
+ "missing file name in line number program header",
2863
+ 0);
2864
+ return 0;
2865
+ }
2866
+
2867
+ if (dir == NULL)
2868
+ *string = path;
2869
+ else
2870
+ {
2871
+ size_t dir_len;
2872
+ size_t path_len;
2873
+ char *s;
2874
+
2875
+ dir_len = strlen (dir);
2876
+ path_len = strlen (path);
2877
+ s = (char *) backtrace_alloc (state, dir_len + path_len + 2,
2878
+ hdr_buf->error_callback, hdr_buf->data);
2879
+ if (s == NULL)
2880
+ return 0;
2881
+ memcpy (s, dir, dir_len);
2882
+ /* FIXME: If we are on a DOS-based file system, and the
2883
+ directory or the path name use backslashes, then we should
2884
+ use a backslash here. */
2885
+ s[dir_len] = '/';
2886
+ memcpy (s + dir_len + 1, path, path_len + 1);
2887
+ *string = s;
2888
+ }
2889
+
2890
+ return 1;
2891
+ }
2892
+
2893
+ /* Read a set of DWARF 5 line header format entries, setting *PCOUNT
2894
+ and *PPATHS. Return 1 on success, 0 on failure. */
2895
+
2896
+ static int
2897
+ read_line_header_format_entries (struct backtrace_state *state,
2898
+ struct dwarf_data *ddata,
2899
+ struct unit *u,
2900
+ struct dwarf_buf *hdr_buf,
2901
+ struct line_header *hdr,
2902
+ size_t *pcount,
2903
+ const char ***ppaths)
2904
+ {
2905
+ size_t formats_count;
2906
+ struct line_header_format *formats;
2907
+ size_t paths_count;
2908
+ const char **paths;
2909
+ size_t i;
2910
+ int ret;
2911
+
2912
+ formats_count = read_byte (hdr_buf);
2913
+ if (formats_count == 0)
2914
+ formats = NULL;
2915
+ else
2916
+ {
2917
+ formats = ((struct line_header_format *)
2918
+ backtrace_alloc (state,
2919
+ (formats_count
2920
+ * sizeof (struct line_header_format)),
2921
+ hdr_buf->error_callback,
2922
+ hdr_buf->data));
2923
+ if (formats == NULL)
2924
+ return 0;
2925
+
2926
+ for (i = 0; i < formats_count; i++)
2927
+ {
2928
+ formats[i].lnct = (int) read_uleb128(hdr_buf);
2929
+ formats[i].form = (enum dwarf_form) read_uleb128 (hdr_buf);
2930
+ }
2931
+ }
2932
+
2933
+ paths_count = read_uleb128 (hdr_buf);
2934
+ if (paths_count == 0)
2935
+ {
2936
+ *pcount = 0;
2937
+ *ppaths = NULL;
2938
+ ret = 1;
2939
+ goto exit;
2940
+ }
2941
+
2942
+ paths = ((const char **)
2943
+ backtrace_alloc (state, paths_count * sizeof (const char *),
2944
+ hdr_buf->error_callback, hdr_buf->data));
2945
+ if (paths == NULL)
2946
+ {
2947
+ ret = 0;
2948
+ goto exit;
2949
+ }
2950
+ for (i = 0; i < paths_count; i++)
2951
+ {
2952
+ if (!read_lnct (state, ddata, u, hdr_buf, hdr, formats_count,
2953
+ formats, &paths[i]))
2954
+ {
2955
+ backtrace_free (state, paths,
2956
+ paths_count * sizeof (const char *),
2957
+ hdr_buf->error_callback, hdr_buf->data);
2958
+ ret = 0;
2959
+ goto exit;
2960
+ }
2961
+ }
2962
+
2963
+ *pcount = paths_count;
2964
+ *ppaths = paths;
2965
+
2966
+ ret = 1;
2967
+
2968
+ exit:
2969
+ if (formats != NULL)
2970
+ backtrace_free (state, formats,
2971
+ formats_count * sizeof (struct line_header_format),
2972
+ hdr_buf->error_callback, hdr_buf->data);
2973
+
2974
+ return ret;
2975
+ }
2976
+
2977
+ /* Read the line header. Return 1 on success, 0 on failure. */
2978
+
2979
+ static int
2980
+ read_line_header (struct backtrace_state *state, struct dwarf_data *ddata,
2981
+ struct unit *u, int is_dwarf64, struct dwarf_buf *line_buf,
2982
+ struct line_header *hdr)
2983
+ {
2984
+ uint64_t hdrlen;
2985
+ struct dwarf_buf hdr_buf;
2986
+
2987
+ hdr->version = read_uint16 (line_buf);
2988
+ if (hdr->version < 2 || hdr->version > 5)
2989
+ {
2990
+ dwarf_buf_error (line_buf, "unsupported line number version", -1);
2991
+ return 0;
2992
+ }
2993
+
2994
+ if (hdr->version < 5)
2995
+ hdr->addrsize = u->addrsize;
2996
+ else
2997
+ {
2998
+ hdr->addrsize = read_byte (line_buf);
2999
+ /* We could support a non-zero segment_selector_size but I doubt
3000
+ we'll ever see it. */
3001
+ if (read_byte (line_buf) != 0)
3002
+ {
3003
+ dwarf_buf_error (line_buf,
3004
+ "non-zero segment_selector_size not supported",
3005
+ -1);
3006
+ return 0;
3007
+ }
3008
+ }
3009
+
3010
+ hdrlen = read_offset (line_buf, is_dwarf64);
3011
+
3012
+ hdr_buf = *line_buf;
3013
+ hdr_buf.left = hdrlen;
3014
+
3015
+ if (!advance (line_buf, hdrlen))
3016
+ return 0;
3017
+
3018
+ hdr->min_insn_len = read_byte (&hdr_buf);
3019
+ if (hdr->version < 4)
3020
+ hdr->max_ops_per_insn = 1;
3021
+ else
3022
+ hdr->max_ops_per_insn = read_byte (&hdr_buf);
3023
+
3024
+ /* We don't care about default_is_stmt. */
3025
+ read_byte (&hdr_buf);
3026
+
3027
+ hdr->line_base = read_sbyte (&hdr_buf);
3028
+ hdr->line_range = read_byte (&hdr_buf);
3029
+
3030
+ hdr->opcode_base = read_byte (&hdr_buf);
3031
+ hdr->opcode_lengths = hdr_buf.buf;
3032
+ if (!advance (&hdr_buf, hdr->opcode_base - 1))
3033
+ return 0;
3034
+
3035
+ if (hdr->version < 5)
3036
+ {
3037
+ if (!read_v2_paths (state, u, &hdr_buf, hdr))
3038
+ return 0;
3039
+ }
3040
+ else
3041
+ {
3042
+ if (!read_line_header_format_entries (state, ddata, u, &hdr_buf, hdr,
3043
+ &hdr->dirs_count,
3044
+ &hdr->dirs))
3045
+ return 0;
3046
+ if (!read_line_header_format_entries (state, ddata, u, &hdr_buf, hdr,
3047
+ &hdr->filenames_count,
3048
+ &hdr->filenames))
3049
+ return 0;
3050
+ }
3051
+
3052
+ if (hdr_buf.reported_underflow)
3053
+ return 0;
3054
+
3055
+ return 1;
3056
+ }
3057
+
3058
+ /* Read the line program, adding line mappings to VEC. Return 1 on
3059
+ success, 0 on failure. */
3060
+
3061
+ static int
3062
+ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
3063
+ const struct line_header *hdr, struct dwarf_buf *line_buf,
3064
+ struct line_vector *vec)
3065
+ {
3066
+ uint64_t address;
3067
+ unsigned int op_index;
3068
+ const char *reset_filename;
3069
+ const char *filename;
3070
+ int lineno;
3071
+
3072
+ address = 0;
3073
+ op_index = 0;
3074
+ if (hdr->filenames_count > 1)
3075
+ reset_filename = hdr->filenames[1];
3076
+ else
3077
+ reset_filename = "";
3078
+ filename = reset_filename;
3079
+ lineno = 1;
3080
+ while (line_buf->left > 0)
3081
+ {
3082
+ unsigned int op;
3083
+
3084
+ op = read_byte (line_buf);
3085
+ if (op >= hdr->opcode_base)
3086
+ {
3087
+ unsigned int advance;
3088
+
3089
+ /* Special opcode. */
3090
+ op -= hdr->opcode_base;
3091
+ advance = op / hdr->line_range;
3092
+ address += (hdr->min_insn_len * (op_index + advance)
3093
+ / hdr->max_ops_per_insn);
3094
+ op_index = (op_index + advance) % hdr->max_ops_per_insn;
3095
+ lineno += hdr->line_base + (int) (op % hdr->line_range);
3096
+ add_line (state, ddata, address, filename, lineno,
3097
+ line_buf->error_callback, line_buf->data, vec);
3098
+ }
3099
+ else if (op == DW_LNS_extended_op)
3100
+ {
3101
+ uint64_t len;
3102
+
3103
+ len = read_uleb128 (line_buf);
3104
+ op = read_byte (line_buf);
3105
+ switch (op)
3106
+ {
3107
+ case DW_LNE_end_sequence:
3108
+ /* FIXME: Should we mark the high PC here? It seems
3109
+ that we already have that information from the
3110
+ compilation unit. */
3111
+ address = 0;
3112
+ op_index = 0;
3113
+ filename = reset_filename;
3114
+ lineno = 1;
3115
+ break;
3116
+ case DW_LNE_set_address:
3117
+ address = read_address (line_buf, hdr->addrsize);
3118
+ break;
3119
+ case DW_LNE_define_file:
3120
+ {
3121
+ const char *f;
3122
+ unsigned int dir_index;
3123
+
3124
+ f = read_string (line_buf);
3125
+ if (f == NULL)
3126
+ return 0;
3127
+ dir_index = read_uleb128 (line_buf);
3128
+ /* Ignore that time and length. */
3129
+ read_uleb128 (line_buf);
3130
+ read_uleb128 (line_buf);
3131
+ if (IS_ABSOLUTE_PATH (f))
3132
+ filename = f;
3133
+ else
3134
+ {
3135
+ const char *dir;
3136
+ size_t dir_len;
3137
+ size_t f_len;
3138
+ char *p;
3139
+
3140
+ if (dir_index < hdr->dirs_count)
3141
+ dir = hdr->dirs[dir_index];
3142
+ else
3143
+ {
3144
+ dwarf_buf_error (line_buf,
3145
+ ("invalid directory index "
3146
+ "in line number program"),
3147
+ 0);
3148
+ return 0;
3149
+ }
3150
+ dir_len = strlen (dir);
3151
+ f_len = strlen (f);
3152
+ p = ((char *)
3153
+ backtrace_alloc (state, dir_len + f_len + 2,
3154
+ line_buf->error_callback,
3155
+ line_buf->data));
3156
+ if (p == NULL)
3157
+ return 0;
3158
+ memcpy (p, dir, dir_len);
3159
+ /* FIXME: If we are on a DOS-based file system,
3160
+ and the directory or the file name use
3161
+ backslashes, then we should use a backslash
3162
+ here. */
3163
+ p[dir_len] = '/';
3164
+ memcpy (p + dir_len + 1, f, f_len + 1);
3165
+ filename = p;
3166
+ }
3167
+ }
3168
+ break;
3169
+ case DW_LNE_set_discriminator:
3170
+ /* We don't care about discriminators. */
3171
+ read_uleb128 (line_buf);
3172
+ break;
3173
+ default:
3174
+ if (!advance (line_buf, len - 1))
3175
+ return 0;
3176
+ break;
3177
+ }
3178
+ }
3179
+ else
3180
+ {
3181
+ switch (op)
3182
+ {
3183
+ case DW_LNS_copy:
3184
+ add_line (state, ddata, address, filename, lineno,
3185
+ line_buf->error_callback, line_buf->data, vec);
3186
+ break;
3187
+ case DW_LNS_advance_pc:
3188
+ {
3189
+ uint64_t advance;
3190
+
3191
+ advance = read_uleb128 (line_buf);
3192
+ address += (hdr->min_insn_len * (op_index + advance)
3193
+ / hdr->max_ops_per_insn);
3194
+ op_index = (op_index + advance) % hdr->max_ops_per_insn;
3195
+ }
3196
+ break;
3197
+ case DW_LNS_advance_line:
3198
+ lineno += (int) read_sleb128 (line_buf);
3199
+ break;
3200
+ case DW_LNS_set_file:
3201
+ {
3202
+ uint64_t fileno;
3203
+
3204
+ fileno = read_uleb128 (line_buf);
3205
+ if (fileno >= hdr->filenames_count)
3206
+ {
3207
+ dwarf_buf_error (line_buf,
3208
+ ("invalid file number in "
3209
+ "line number program"),
3210
+ 0);
3211
+ return 0;
3212
+ }
3213
+ filename = hdr->filenames[fileno];
3214
+ }
3215
+ break;
3216
+ case DW_LNS_set_column:
3217
+ read_uleb128 (line_buf);
3218
+ break;
3219
+ case DW_LNS_negate_stmt:
3220
+ break;
3221
+ case DW_LNS_set_basic_block:
3222
+ break;
3223
+ case DW_LNS_const_add_pc:
3224
+ {
3225
+ unsigned int advance;
3226
+
3227
+ op = 255 - hdr->opcode_base;
3228
+ advance = op / hdr->line_range;
3229
+ address += (hdr->min_insn_len * (op_index + advance)
3230
+ / hdr->max_ops_per_insn);
3231
+ op_index = (op_index + advance) % hdr->max_ops_per_insn;
3232
+ }
3233
+ break;
3234
+ case DW_LNS_fixed_advance_pc:
3235
+ address += read_uint16 (line_buf);
3236
+ op_index = 0;
3237
+ break;
3238
+ case DW_LNS_set_prologue_end:
3239
+ break;
3240
+ case DW_LNS_set_epilogue_begin:
3241
+ break;
3242
+ case DW_LNS_set_isa:
3243
+ read_uleb128 (line_buf);
3244
+ break;
3245
+ default:
3246
+ {
3247
+ unsigned int i;
3248
+
3249
+ for (i = hdr->opcode_lengths[op - 1]; i > 0; --i)
3250
+ read_uleb128 (line_buf);
3251
+ }
3252
+ break;
3253
+ }
3254
+ }
3255
+ }
3256
+
3257
+ return 1;
3258
+ }
3259
+
3260
+ /* Read the line number information for a compilation unit. Returns 1
3261
+ on success, 0 on failure. */
3262
+
3263
+ static int
3264
+ read_line_info (struct backtrace_state *state, struct dwarf_data *ddata,
3265
+ backtrace_error_callback error_callback, void *data,
3266
+ struct unit *u, struct line_header *hdr, struct line **lines,
3267
+ size_t *lines_count)
3268
+ {
3269
+ struct line_vector vec;
3270
+ struct dwarf_buf line_buf;
3271
+ uint64_t len;
3272
+ int is_dwarf64;
3273
+ struct line *ln;
3274
+
3275
+ memset (&vec.vec, 0, sizeof vec.vec);
3276
+ vec.count = 0;
3277
+
3278
+ memset (hdr, 0, sizeof *hdr);
3279
+
3280
+ if (u->lineoff != (off_t) (size_t) u->lineoff
3281
+ || (size_t) u->lineoff >= ddata->dwarf_sections.size[DEBUG_LINE])
3282
+ {
3283
+ error_callback (data, "unit line offset out of range", 0);
3284
+ goto fail;
3285
+ }
3286
+
3287
+ line_buf.name = ".debug_line";
3288
+ line_buf.start = ddata->dwarf_sections.data[DEBUG_LINE];
3289
+ line_buf.buf = ddata->dwarf_sections.data[DEBUG_LINE] + u->lineoff;
3290
+ line_buf.left = ddata->dwarf_sections.size[DEBUG_LINE] - u->lineoff;
3291
+ line_buf.is_bigendian = ddata->is_bigendian;
3292
+ line_buf.error_callback = error_callback;
3293
+ line_buf.data = data;
3294
+ line_buf.reported_underflow = 0;
3295
+
3296
+ len = read_initial_length (&line_buf, &is_dwarf64);
3297
+ line_buf.left = len;
3298
+
3299
+ if (!read_line_header (state, ddata, u, is_dwarf64, &line_buf, hdr))
3300
+ goto fail;
3301
+
3302
+ if (!read_line_program (state, ddata, hdr, &line_buf, &vec))
3303
+ goto fail;
3304
+
3305
+ if (line_buf.reported_underflow)
3306
+ goto fail;
3307
+
3308
+ if (vec.count == 0)
3309
+ {
3310
+ /* This is not a failure in the sense of a generating an error,
3311
+ but it is a failure in that sense that we have no useful
3312
+ information. */
3313
+ goto fail;
3314
+ }
3315
+
3316
+ /* Allocate one extra entry at the end. */
3317
+ ln = ((struct line *)
3318
+ backtrace_vector_grow (state, sizeof (struct line), error_callback,
3319
+ data, &vec.vec));
3320
+ if (ln == NULL)
3321
+ goto fail;
3322
+ ln->pc = (uintptr_t) -1;
3323
+ ln->filename = NULL;
3324
+ ln->lineno = 0;
3325
+ ln->idx = 0;
3326
+
3327
+ if (!backtrace_vector_release (state, &vec.vec, error_callback, data))
3328
+ goto fail;
3329
+
3330
+ ln = (struct line *) vec.vec.base;
3331
+ backtrace_qsort (ln, vec.count, sizeof (struct line), line_compare);
3332
+
3333
+ *lines = ln;
3334
+ *lines_count = vec.count;
3335
+
3336
+ return 1;
3337
+
3338
+ fail:
3339
+ backtrace_vector_free (state, &vec.vec, error_callback, data);
3340
+ free_line_header (state, hdr, error_callback, data);
3341
+ *lines = (struct line *) (uintptr_t) -1;
3342
+ *lines_count = 0;
3343
+ return 0;
3344
+ }
3345
+
3346
+ static const char *read_referenced_name (struct dwarf_data *, struct unit *,
3347
+ uint64_t, backtrace_error_callback,
3348
+ void *);
3349
+
3350
+ /* Read the name of a function from a DIE referenced by ATTR with VAL. */
3351
+
3352
+ static const char *
3353
+ read_referenced_name_from_attr (struct dwarf_data *ddata, struct unit *u,
3354
+ struct attr *attr, struct attr_val *val,
3355
+ backtrace_error_callback error_callback,
3356
+ void *data)
3357
+ {
3358
+ switch (attr->name)
3359
+ {
3360
+ case DW_AT_abstract_origin:
3361
+ case DW_AT_specification:
3362
+ break;
3363
+ default:
3364
+ return NULL;
3365
+ }
3366
+
3367
+ if (attr->form == DW_FORM_ref_sig8)
3368
+ return NULL;
3369
+
3370
+ if (val->encoding == ATTR_VAL_REF_INFO)
3371
+ {
3372
+ struct unit *unit
3373
+ = find_unit (ddata->units, ddata->units_count,
3374
+ val->u.uint);
3375
+ if (unit == NULL)
3376
+ return NULL;
3377
+
3378
+ uint64_t offset = val->u.uint - unit->low_offset;
3379
+ return read_referenced_name (ddata, unit, offset, error_callback, data);
3380
+ }
3381
+
3382
+ if (val->encoding == ATTR_VAL_UINT
3383
+ || val->encoding == ATTR_VAL_REF_UNIT)
3384
+ return read_referenced_name (ddata, u, val->u.uint, error_callback, data);
3385
+
3386
+ if (val->encoding == ATTR_VAL_REF_ALT_INFO)
3387
+ {
3388
+ struct unit *alt_unit
3389
+ = find_unit (ddata->altlink->units, ddata->altlink->units_count,
3390
+ val->u.uint);
3391
+ if (alt_unit == NULL)
3392
+ return NULL;
3393
+
3394
+ uint64_t offset = val->u.uint - alt_unit->low_offset;
3395
+ return read_referenced_name (ddata->altlink, alt_unit, offset,
3396
+ error_callback, data);
3397
+ }
3398
+
3399
+ return NULL;
3400
+ }
3401
+
3402
+ /* Read the name of a function from a DIE referenced by a
3403
+ DW_AT_abstract_origin or DW_AT_specification tag. OFFSET is within
3404
+ the same compilation unit. */
3405
+
3406
+ static const char *
3407
+ read_referenced_name (struct dwarf_data *ddata, struct unit *u,
3408
+ uint64_t offset, backtrace_error_callback error_callback,
3409
+ void *data)
3410
+ {
3411
+ struct dwarf_buf unit_buf;
3412
+ uint64_t code;
3413
+ const struct abbrev *abbrev;
3414
+ const char *ret;
3415
+ size_t i;
3416
+
3417
+ /* OFFSET is from the start of the data for this compilation unit.
3418
+ U->unit_data is the data, but it starts U->unit_data_offset bytes
3419
+ from the beginning. */
3420
+
3421
+ if (offset < u->unit_data_offset
3422
+ || offset - u->unit_data_offset >= u->unit_data_len)
3423
+ {
3424
+ error_callback (data,
3425
+ "abstract origin or specification out of range",
3426
+ 0);
3427
+ return NULL;
3428
+ }
3429
+
3430
+ offset -= u->unit_data_offset;
3431
+
3432
+ unit_buf.name = ".debug_info";
3433
+ unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO];
3434
+ unit_buf.buf = u->unit_data + offset;
3435
+ unit_buf.left = u->unit_data_len - offset;
3436
+ unit_buf.is_bigendian = ddata->is_bigendian;
3437
+ unit_buf.error_callback = error_callback;
3438
+ unit_buf.data = data;
3439
+ unit_buf.reported_underflow = 0;
3440
+
3441
+ code = read_uleb128 (&unit_buf);
3442
+ if (code == 0)
3443
+ {
3444
+ dwarf_buf_error (&unit_buf,
3445
+ "invalid abstract origin or specification",
3446
+ 0);
3447
+ return NULL;
3448
+ }
3449
+
3450
+ abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
3451
+ if (abbrev == NULL)
3452
+ return NULL;
3453
+
3454
+ ret = NULL;
3455
+ for (i = 0; i < abbrev->num_attrs; ++i)
3456
+ {
3457
+ struct attr_val val;
3458
+
3459
+ if (!read_attribute (abbrev->attrs[i].form, abbrev->attrs[i].val,
3460
+ &unit_buf, u->is_dwarf64, u->version, u->addrsize,
3461
+ &ddata->dwarf_sections, ddata->altlink, &val))
3462
+ return NULL;
3463
+
3464
+ switch (abbrev->attrs[i].name)
3465
+ {
3466
+ case DW_AT_name:
3467
+ /* Third name preference: don't override. A name we found in some
3468
+ other way, will normally be more useful -- e.g., this name is
3469
+ normally not mangled. */
3470
+ if (ret != NULL)
3471
+ break;
3472
+ if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3473
+ ddata->is_bigendian, u->str_offsets_base,
3474
+ &val, error_callback, data, &ret))
3475
+ return NULL;
3476
+ break;
3477
+
3478
+ case DW_AT_linkage_name:
3479
+ case DW_AT_MIPS_linkage_name:
3480
+ /* First name preference: override all. */
3481
+ {
3482
+ const char *s;
3483
+
3484
+ s = NULL;
3485
+ if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3486
+ ddata->is_bigendian, u->str_offsets_base,
3487
+ &val, error_callback, data, &s))
3488
+ return NULL;
3489
+ if (s != NULL)
3490
+ return s;
3491
+ }
3492
+ break;
3493
+
3494
+ case DW_AT_specification:
3495
+ /* Second name preference: override DW_AT_name, don't override
3496
+ DW_AT_linkage_name. */
3497
+ {
3498
+ const char *name;
3499
+
3500
+ name = read_referenced_name_from_attr (ddata, u, &abbrev->attrs[i],
3501
+ &val, error_callback, data);
3502
+ if (name != NULL)
3503
+ ret = name;
3504
+ }
3505
+ break;
3506
+
3507
+ default:
3508
+ break;
3509
+ }
3510
+ }
3511
+
3512
+ return ret;
3513
+ }
3514
+
3515
+ /* Add a range to a unit that maps to a function. This is called via
3516
+ add_ranges. Returns 1 on success, 0 on error. */
3517
+
3518
+ static int
3519
+ add_function_range (struct backtrace_state *state, void *rdata,
3520
+ uintptr_t lowpc, uintptr_t highpc,
3521
+ backtrace_error_callback error_callback, void *data,
3522
+ void *pvec)
3523
+ {
3524
+ struct function *function = (struct function *) rdata;
3525
+ struct function_vector *vec = (struct function_vector *) pvec;
3526
+ struct function_addrs *p;
3527
+
3528
+ if (vec->count > 0)
3529
+ {
3530
+ p = (struct function_addrs *) vec->vec.base + (vec->count - 1);
3531
+ if ((lowpc == p->high || lowpc == p->high + 1)
3532
+ && function == p->function)
3533
+ {
3534
+ if (highpc > p->high)
3535
+ p->high = highpc;
3536
+ return 1;
3537
+ }
3538
+ }
3539
+
3540
+ p = ((struct function_addrs *)
3541
+ backtrace_vector_grow (state, sizeof (struct function_addrs),
3542
+ error_callback, data, &vec->vec));
3543
+ if (p == NULL)
3544
+ return 0;
3545
+
3546
+ p->low = lowpc;
3547
+ p->high = highpc;
3548
+ p->function = function;
3549
+
3550
+ ++vec->count;
3551
+
3552
+ return 1;
3553
+ }
3554
+
3555
+ /* Read one entry plus all its children. Add function addresses to
3556
+ VEC. Returns 1 on success, 0 on error. */
3557
+
3558
+ static int
3559
+ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
3560
+ struct unit *u, uintptr_t base, struct dwarf_buf *unit_buf,
3561
+ const struct line_header *lhdr,
3562
+ backtrace_error_callback error_callback, void *data,
3563
+ struct function_vector *vec_function,
3564
+ struct function_vector *vec_inlined)
3565
+ {
3566
+ while (unit_buf->left > 0)
3567
+ {
3568
+ uint64_t code;
3569
+ const struct abbrev *abbrev;
3570
+ int is_function;
3571
+ struct function *function;
3572
+ struct function_vector *vec;
3573
+ size_t i;
3574
+ struct pcrange pcrange;
3575
+ int have_linkage_name;
3576
+
3577
+ code = read_uleb128 (unit_buf);
3578
+ if (code == 0)
3579
+ return 1;
3580
+
3581
+ abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
3582
+ if (abbrev == NULL)
3583
+ return 0;
3584
+
3585
+ is_function = (abbrev->tag == DW_TAG_subprogram
3586
+ || abbrev->tag == DW_TAG_entry_point
3587
+ || abbrev->tag == DW_TAG_inlined_subroutine);
3588
+
3589
+ if (abbrev->tag == DW_TAG_inlined_subroutine)
3590
+ vec = vec_inlined;
3591
+ else
3592
+ vec = vec_function;
3593
+
3594
+ function = NULL;
3595
+ if (is_function)
3596
+ {
3597
+ function = ((struct function *)
3598
+ backtrace_alloc (state, sizeof *function,
3599
+ error_callback, data));
3600
+ if (function == NULL)
3601
+ return 0;
3602
+ memset (function, 0, sizeof *function);
3603
+ }
3604
+
3605
+ memset (&pcrange, 0, sizeof pcrange);
3606
+ have_linkage_name = 0;
3607
+ for (i = 0; i < abbrev->num_attrs; ++i)
3608
+ {
3609
+ struct attr_val val;
3610
+
3611
+ if (!read_attribute (abbrev->attrs[i].form, abbrev->attrs[i].val,
3612
+ unit_buf, u->is_dwarf64, u->version,
3613
+ u->addrsize, &ddata->dwarf_sections,
3614
+ ddata->altlink, &val))
3615
+ return 0;
3616
+
3617
+ /* The compile unit sets the base address for any address
3618
+ ranges in the function entries. */
3619
+ if ((abbrev->tag == DW_TAG_compile_unit
3620
+ || abbrev->tag == DW_TAG_skeleton_unit)
3621
+ && abbrev->attrs[i].name == DW_AT_low_pc)
3622
+ {
3623
+ if (val.encoding == ATTR_VAL_ADDRESS)
3624
+ base = (uintptr_t) val.u.uint;
3625
+ else if (val.encoding == ATTR_VAL_ADDRESS_INDEX)
3626
+ {
3627
+ if (!resolve_addr_index (&ddata->dwarf_sections,
3628
+ u->addr_base, u->addrsize,
3629
+ ddata->is_bigendian, val.u.uint,
3630
+ error_callback, data, &base))
3631
+ return 0;
3632
+ }
3633
+ }
3634
+
3635
+ if (is_function)
3636
+ {
3637
+ switch (abbrev->attrs[i].name)
3638
+ {
3639
+ case DW_AT_call_file:
3640
+ if (val.encoding == ATTR_VAL_UINT)
3641
+ {
3642
+ if (val.u.uint >= lhdr->filenames_count)
3643
+ {
3644
+ dwarf_buf_error (unit_buf,
3645
+ ("invalid file number in "
3646
+ "DW_AT_call_file attribute"),
3647
+ 0);
3648
+ return 0;
3649
+ }
3650
+ function->caller_filename = lhdr->filenames[val.u.uint];
3651
+ }
3652
+ break;
3653
+
3654
+ case DW_AT_call_line:
3655
+ if (val.encoding == ATTR_VAL_UINT)
3656
+ function->caller_lineno = val.u.uint;
3657
+ break;
3658
+
3659
+ case DW_AT_abstract_origin:
3660
+ case DW_AT_specification:
3661
+ /* Second name preference: override DW_AT_name, don't override
3662
+ DW_AT_linkage_name. */
3663
+ if (have_linkage_name)
3664
+ break;
3665
+ {
3666
+ const char *name;
3667
+
3668
+ name
3669
+ = read_referenced_name_from_attr (ddata, u,
3670
+ &abbrev->attrs[i], &val,
3671
+ error_callback, data);
3672
+ if (name != NULL)
3673
+ function->name = name;
3674
+ }
3675
+ break;
3676
+
3677
+ case DW_AT_name:
3678
+ /* Third name preference: don't override. */
3679
+ if (function->name != NULL)
3680
+ break;
3681
+ if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3682
+ ddata->is_bigendian,
3683
+ u->str_offsets_base, &val,
3684
+ error_callback, data, &function->name))
3685
+ return 0;
3686
+ break;
3687
+
3688
+ case DW_AT_linkage_name:
3689
+ case DW_AT_MIPS_linkage_name:
3690
+ /* First name preference: override all. */
3691
+ {
3692
+ const char *s;
3693
+
3694
+ s = NULL;
3695
+ if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3696
+ ddata->is_bigendian,
3697
+ u->str_offsets_base, &val,
3698
+ error_callback, data, &s))
3699
+ return 0;
3700
+ if (s != NULL)
3701
+ {
3702
+ function->name = s;
3703
+ have_linkage_name = 1;
3704
+ }
3705
+ }
3706
+ break;
3707
+
3708
+ case DW_AT_low_pc: case DW_AT_high_pc: case DW_AT_ranges:
3709
+ update_pcrange (&abbrev->attrs[i], &val, &pcrange);
3710
+ break;
3711
+
3712
+ default:
3713
+ break;
3714
+ }
3715
+ }
3716
+ }
3717
+
3718
+ /* If we couldn't find a name for the function, we have no use
3719
+ for it. */
3720
+ if (is_function && function->name == NULL)
3721
+ {
3722
+ backtrace_free (state, function, sizeof *function,
3723
+ error_callback, data);
3724
+ is_function = 0;
3725
+ }
3726
+
3727
+ if (is_function)
3728
+ {
3729
+ if (pcrange.have_ranges
3730
+ || (pcrange.have_lowpc && pcrange.have_highpc))
3731
+ {
3732
+ if (!add_ranges (state, &ddata->dwarf_sections,
3733
+ ddata->base_address, ddata->is_bigendian,
3734
+ u, base, &pcrange, add_function_range,
3735
+ (void *) function, error_callback, data,
3736
+ (void *) vec))
3737
+ return 0;
3738
+ }
3739
+ else
3740
+ {
3741
+ backtrace_free (state, function, sizeof *function,
3742
+ error_callback, data);
3743
+ is_function = 0;
3744
+ }
3745
+ }
3746
+
3747
+ if (abbrev->has_children)
3748
+ {
3749
+ if (!is_function)
3750
+ {
3751
+ if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr,
3752
+ error_callback, data, vec_function,
3753
+ vec_inlined))
3754
+ return 0;
3755
+ }
3756
+ else
3757
+ {
3758
+ struct function_vector fvec;
3759
+
3760
+ /* Gather any information for inlined functions in
3761
+ FVEC. */
3762
+
3763
+ memset (&fvec, 0, sizeof fvec);
3764
+
3765
+ if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr,
3766
+ error_callback, data, vec_function,
3767
+ &fvec))
3768
+ return 0;
3769
+
3770
+ if (fvec.count > 0)
3771
+ {
3772
+ struct function_addrs *p;
3773
+ struct function_addrs *faddrs;
3774
+
3775
+ /* Allocate a trailing entry, but don't include it
3776
+ in fvec.count. */
3777
+ p = ((struct function_addrs *)
3778
+ backtrace_vector_grow (state,
3779
+ sizeof (struct function_addrs),
3780
+ error_callback, data,
3781
+ &fvec.vec));
3782
+ if (p == NULL)
3783
+ return 0;
3784
+ p->low = 0;
3785
+ --p->low;
3786
+ p->high = p->low;
3787
+ p->function = NULL;
3788
+
3789
+ if (!backtrace_vector_release (state, &fvec.vec,
3790
+ error_callback, data))
3791
+ return 0;
3792
+
3793
+ faddrs = (struct function_addrs *) fvec.vec.base;
3794
+ backtrace_qsort (faddrs, fvec.count,
3795
+ sizeof (struct function_addrs),
3796
+ function_addrs_compare);
3797
+
3798
+ function->function_addrs = faddrs;
3799
+ function->function_addrs_count = fvec.count;
3800
+ }
3801
+ }
3802
+ }
3803
+ }
3804
+
3805
+ return 1;
3806
+ }
3807
+
3808
+ /* Read function name information for a compilation unit. We look
3809
+ through the whole unit looking for function tags. */
3810
+
3811
+ static void
3812
+ read_function_info (struct backtrace_state *state, struct dwarf_data *ddata,
3813
+ const struct line_header *lhdr,
3814
+ backtrace_error_callback error_callback, void *data,
3815
+ struct unit *u, struct function_vector *fvec,
3816
+ struct function_addrs **ret_addrs,
3817
+ size_t *ret_addrs_count)
3818
+ {
3819
+ struct function_vector lvec;
3820
+ struct function_vector *pfvec;
3821
+ struct dwarf_buf unit_buf;
3822
+ struct function_addrs *p;
3823
+ struct function_addrs *addrs;
3824
+ size_t addrs_count;
3825
+
3826
+ /* Use FVEC if it is not NULL. Otherwise use our own vector. */
3827
+ if (fvec != NULL)
3828
+ pfvec = fvec;
3829
+ else
3830
+ {
3831
+ memset (&lvec, 0, sizeof lvec);
3832
+ pfvec = &lvec;
3833
+ }
3834
+
3835
+ unit_buf.name = ".debug_info";
3836
+ unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO];
3837
+ unit_buf.buf = u->unit_data;
3838
+ unit_buf.left = u->unit_data_len;
3839
+ unit_buf.is_bigendian = ddata->is_bigendian;
3840
+ unit_buf.error_callback = error_callback;
3841
+ unit_buf.data = data;
3842
+ unit_buf.reported_underflow = 0;
3843
+
3844
+ while (unit_buf.left > 0)
3845
+ {
3846
+ if (!read_function_entry (state, ddata, u, 0, &unit_buf, lhdr,
3847
+ error_callback, data, pfvec, pfvec))
3848
+ return;
3849
+ }
3850
+
3851
+ if (pfvec->count == 0)
3852
+ return;
3853
+
3854
+ /* Allocate a trailing entry, but don't include it in
3855
+ pfvec->count. */
3856
+ p = ((struct function_addrs *)
3857
+ backtrace_vector_grow (state, sizeof (struct function_addrs),
3858
+ error_callback, data, &pfvec->vec));
3859
+ if (p == NULL)
3860
+ return;
3861
+ p->low = 0;
3862
+ --p->low;
3863
+ p->high = p->low;
3864
+ p->function = NULL;
3865
+
3866
+ addrs_count = pfvec->count;
3867
+
3868
+ if (fvec == NULL)
3869
+ {
3870
+ if (!backtrace_vector_release (state, &lvec.vec, error_callback, data))
3871
+ return;
3872
+ addrs = (struct function_addrs *) pfvec->vec.base;
3873
+ }
3874
+ else
3875
+ {
3876
+ /* Finish this list of addresses, but leave the remaining space in
3877
+ the vector available for the next function unit. */
3878
+ addrs = ((struct function_addrs *)
3879
+ backtrace_vector_finish (state, &fvec->vec,
3880
+ error_callback, data));
3881
+ if (addrs == NULL)
3882
+ return;
3883
+ fvec->count = 0;
3884
+ }
3885
+
3886
+ backtrace_qsort (addrs, addrs_count, sizeof (struct function_addrs),
3887
+ function_addrs_compare);
3888
+
3889
+ *ret_addrs = addrs;
3890
+ *ret_addrs_count = addrs_count;
3891
+ }
3892
+
3893
+ /* See if PC is inlined in FUNCTION. If it is, print out the inlined
3894
+ information, and update FILENAME and LINENO for the caller.
3895
+ Returns whatever CALLBACK returns, or 0 to keep going. */
3896
+
3897
+ static int
3898
+ report_inlined_functions (uintptr_t pc, struct function *function,
3899
+ backtrace_full_callback callback, void *data,
3900
+ const char **filename, int *lineno)
3901
+ {
3902
+ struct function_addrs *p;
3903
+ struct function_addrs *match;
3904
+ struct function *inlined;
3905
+ int ret;
3906
+
3907
+ if (function->function_addrs_count == 0)
3908
+ return 0;
3909
+
3910
+ /* Our search isn't safe if pc == -1, as that is the sentinel
3911
+ value. */
3912
+ if (pc + 1 == 0)
3913
+ return 0;
3914
+
3915
+ p = ((struct function_addrs *)
3916
+ bsearch (&pc, function->function_addrs,
3917
+ function->function_addrs_count,
3918
+ sizeof (struct function_addrs),
3919
+ function_addrs_search));
3920
+ if (p == NULL)
3921
+ return 0;
3922
+
3923
+ /* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
3924
+ sorted by low, so if pc > p->low we are at the end of a range of
3925
+ function_addrs with the same low value. If pc == p->low walk
3926
+ forward to the end of the range with that low value. Then walk
3927
+ backward and use the first range that includes pc. */
3928
+ while (pc == (p + 1)->low)
3929
+ ++p;
3930
+ match = NULL;
3931
+ while (1)
3932
+ {
3933
+ if (pc < p->high)
3934
+ {
3935
+ match = p;
3936
+ break;
3937
+ }
3938
+ if (p == function->function_addrs)
3939
+ break;
3940
+ if ((p - 1)->low < p->low)
3941
+ break;
3942
+ --p;
3943
+ }
3944
+ if (match == NULL)
3945
+ return 0;
3946
+
3947
+ /* We found an inlined call. */
3948
+
3949
+ inlined = match->function;
3950
+
3951
+ /* Report any calls inlined into this one. */
3952
+ ret = report_inlined_functions (pc, inlined, callback, data,
3953
+ filename, lineno);
3954
+ if (ret != 0)
3955
+ return ret;
3956
+
3957
+ /* Report this inlined call. */
3958
+ ret = callback (data, pc, *filename, *lineno, inlined->name);
3959
+ if (ret != 0)
3960
+ return ret;
3961
+
3962
+ /* Our caller will report the caller of the inlined function; tell
3963
+ it the appropriate filename and line number. */
3964
+ *filename = inlined->caller_filename;
3965
+ *lineno = inlined->caller_lineno;
3966
+
3967
+ return 0;
3968
+ }
3969
+
3970
+ /* Look for a PC in the DWARF mapping for one module. On success,
3971
+ call CALLBACK and return whatever it returns. On error, call
3972
+ ERROR_CALLBACK and return 0. Sets *FOUND to 1 if the PC is found,
3973
+ 0 if not. */
3974
+
3975
+ static int
3976
+ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
3977
+ uintptr_t pc, backtrace_full_callback callback,
3978
+ backtrace_error_callback error_callback, void *data,
3979
+ int *found)
3980
+ {
3981
+ struct unit_addrs *entry;
3982
+ int found_entry;
3983
+ struct unit *u;
3984
+ int new_data;
3985
+ struct line *lines;
3986
+ struct line *ln;
3987
+ struct function_addrs *p;
3988
+ struct function_addrs *fmatch;
3989
+ struct function *function;
3990
+ const char *filename;
3991
+ int lineno;
3992
+ int ret;
3993
+
3994
+ *found = 1;
3995
+
3996
+ /* Find an address range that includes PC. Our search isn't safe if
3997
+ PC == -1, as we use that as a sentinel value, so skip the search
3998
+ in that case. */
3999
+ entry = (ddata->addrs_count == 0 || pc + 1 == 0
4000
+ ? NULL
4001
+ : bsearch (&pc, ddata->addrs, ddata->addrs_count,
4002
+ sizeof (struct unit_addrs), unit_addrs_search));
4003
+
4004
+ if (entry == NULL)
4005
+ {
4006
+ *found = 0;
4007
+ return 0;
4008
+ }
4009
+
4010
+ /* Here pc >= entry->low && pc < (entry + 1)->low. The unit_addrs
4011
+ are sorted by low, so if pc > p->low we are at the end of a range
4012
+ of unit_addrs with the same low value. If pc == p->low walk
4013
+ forward to the end of the range with that low value. Then walk
4014
+ backward and use the first range that includes pc. */
4015
+ while (pc == (entry + 1)->low)
4016
+ ++entry;
4017
+ found_entry = 0;
4018
+ while (1)
4019
+ {
4020
+ if (pc < entry->high)
4021
+ {
4022
+ found_entry = 1;
4023
+ break;
4024
+ }
4025
+ if (entry == ddata->addrs)
4026
+ break;
4027
+ if ((entry - 1)->low < entry->low)
4028
+ break;
4029
+ --entry;
4030
+ }
4031
+ if (!found_entry)
4032
+ {
4033
+ *found = 0;
4034
+ return 0;
4035
+ }
4036
+
4037
+ /* We need the lines, lines_count, function_addrs,
4038
+ function_addrs_count fields of u. If they are not set, we need
4039
+ to set them. When running in threaded mode, we need to allow for
4040
+ the possibility that some other thread is setting them
4041
+ simultaneously. */
4042
+
4043
+ u = entry->u;
4044
+ lines = u->lines;
4045
+
4046
+ /* Skip units with no useful line number information by walking
4047
+ backward. Useless line number information is marked by setting
4048
+ lines == -1. */
4049
+ while (entry > ddata->addrs
4050
+ && pc >= (entry - 1)->low
4051
+ && pc < (entry - 1)->high)
4052
+ {
4053
+ if (state->threaded)
4054
+ lines = (struct line *) backtrace_atomic_load_pointer (&u->lines);
4055
+
4056
+ if (lines != (struct line *) (uintptr_t) -1)
4057
+ break;
4058
+
4059
+ --entry;
4060
+
4061
+ u = entry->u;
4062
+ lines = u->lines;
4063
+ }
4064
+
4065
+ if (state->threaded)
4066
+ lines = backtrace_atomic_load_pointer (&u->lines);
4067
+
4068
+ new_data = 0;
4069
+ if (lines == NULL)
4070
+ {
4071
+ struct function_addrs *function_addrs;
4072
+ size_t function_addrs_count;
4073
+ struct line_header lhdr;
4074
+ size_t count;
4075
+
4076
+ /* We have never read the line information for this unit. Read
4077
+ it now. */
4078
+
4079
+ function_addrs = NULL;
4080
+ function_addrs_count = 0;
4081
+ if (read_line_info (state, ddata, error_callback, data, entry->u, &lhdr,
4082
+ &lines, &count))
4083
+ {
4084
+ struct function_vector *pfvec;
4085
+
4086
+ /* If not threaded, reuse DDATA->FVEC for better memory
4087
+ consumption. */
4088
+ if (state->threaded)
4089
+ pfvec = NULL;
4090
+ else
4091
+ pfvec = &ddata->fvec;
4092
+ read_function_info (state, ddata, &lhdr, error_callback, data,
4093
+ entry->u, pfvec, &function_addrs,
4094
+ &function_addrs_count);
4095
+ free_line_header (state, &lhdr, error_callback, data);
4096
+ new_data = 1;
4097
+ }
4098
+
4099
+ /* Atomically store the information we just read into the unit.
4100
+ If another thread is simultaneously writing, it presumably
4101
+ read the same information, and we don't care which one we
4102
+ wind up with; we just leak the other one. We do have to
4103
+ write the lines field last, so that the acquire-loads above
4104
+ ensure that the other fields are set. */
4105
+
4106
+ if (!state->threaded)
4107
+ {
4108
+ u->lines_count = count;
4109
+ u->function_addrs = function_addrs;
4110
+ u->function_addrs_count = function_addrs_count;
4111
+ u->lines = lines;
4112
+ }
4113
+ else
4114
+ {
4115
+ backtrace_atomic_store_size_t (&u->lines_count, count);
4116
+ backtrace_atomic_store_pointer (&u->function_addrs, function_addrs);
4117
+ backtrace_atomic_store_size_t (&u->function_addrs_count,
4118
+ function_addrs_count);
4119
+ backtrace_atomic_store_pointer (&u->lines, lines);
4120
+ }
4121
+ }
4122
+
4123
+ /* Now all fields of U have been initialized. */
4124
+
4125
+ if (lines == (struct line *) (uintptr_t) -1)
4126
+ {
4127
+ /* If reading the line number information failed in some way,
4128
+ try again to see if there is a better compilation unit for
4129
+ this PC. */
4130
+ if (new_data)
4131
+ return dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
4132
+ data, found);
4133
+ return callback (data, pc, NULL, 0, NULL);
4134
+ }
4135
+
4136
+ /* Search for PC within this unit. */
4137
+
4138
+ ln = (struct line *) bsearch (&pc, lines, entry->u->lines_count,
4139
+ sizeof (struct line), line_search);
4140
+ if (ln == NULL)
4141
+ {
4142
+ /* The PC is between the low_pc and high_pc attributes of the
4143
+ compilation unit, but no entry in the line table covers it.
4144
+ This implies that the start of the compilation unit has no
4145
+ line number information. */
4146
+
4147
+ if (entry->u->abs_filename == NULL)
4148
+ {
4149
+ const char *filename;
4150
+
4151
+ filename = entry->u->filename;
4152
+ if (filename != NULL
4153
+ && !IS_ABSOLUTE_PATH (filename)
4154
+ && entry->u->comp_dir != NULL)
4155
+ {
4156
+ size_t filename_len;
4157
+ const char *dir;
4158
+ size_t dir_len;
4159
+ char *s;
4160
+
4161
+ filename_len = strlen (filename);
4162
+ dir = entry->u->comp_dir;
4163
+ dir_len = strlen (dir);
4164
+ s = (char *) backtrace_alloc (state, dir_len + filename_len + 2,
4165
+ error_callback, data);
4166
+ if (s == NULL)
4167
+ {
4168
+ *found = 0;
4169
+ return 0;
4170
+ }
4171
+ memcpy (s, dir, dir_len);
4172
+ /* FIXME: Should use backslash if DOS file system. */
4173
+ s[dir_len] = '/';
4174
+ memcpy (s + dir_len + 1, filename, filename_len + 1);
4175
+ filename = s;
4176
+ }
4177
+ entry->u->abs_filename = filename;
4178
+ }
4179
+
4180
+ return callback (data, pc, entry->u->abs_filename, 0, NULL);
4181
+ }
4182
+
4183
+ /* Search for function name within this unit. */
4184
+
4185
+ if (entry->u->function_addrs_count == 0)
4186
+ return callback (data, pc, ln->filename, ln->lineno, NULL);
4187
+
4188
+ p = ((struct function_addrs *)
4189
+ bsearch (&pc, entry->u->function_addrs,
4190
+ entry->u->function_addrs_count,
4191
+ sizeof (struct function_addrs),
4192
+ function_addrs_search));
4193
+ if (p == NULL)
4194
+ return callback (data, pc, ln->filename, ln->lineno, NULL);
4195
+
4196
+ /* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
4197
+ sorted by low, so if pc > p->low we are at the end of a range of
4198
+ function_addrs with the same low value. If pc == p->low walk
4199
+ forward to the end of the range with that low value. Then walk
4200
+ backward and use the first range that includes pc. */
4201
+ while (pc == (p + 1)->low)
4202
+ ++p;
4203
+ fmatch = NULL;
4204
+ while (1)
4205
+ {
4206
+ if (pc < p->high)
4207
+ {
4208
+ fmatch = p;
4209
+ break;
4210
+ }
4211
+ if (p == entry->u->function_addrs)
4212
+ break;
4213
+ if ((p - 1)->low < p->low)
4214
+ break;
4215
+ --p;
4216
+ }
4217
+ if (fmatch == NULL)
4218
+ return callback (data, pc, ln->filename, ln->lineno, NULL);
4219
+
4220
+ function = fmatch->function;
4221
+
4222
+ filename = ln->filename;
4223
+ lineno = ln->lineno;
4224
+
4225
+ ret = report_inlined_functions (pc, function, callback, data,
4226
+ &filename, &lineno);
4227
+ if (ret != 0)
4228
+ return ret;
4229
+
4230
+ return callback (data, pc, filename, lineno, function->name);
4231
+ }
4232
+
4233
+
4234
+ /* Return the file/line information for a PC using the DWARF mapping
4235
+ we built earlier. */
4236
+
4237
+ static int
4238
+ dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
4239
+ backtrace_full_callback callback,
4240
+ backtrace_error_callback error_callback, void *data)
4241
+ {
4242
+ struct dwarf_data *ddata;
4243
+ int found;
4244
+ int ret;
4245
+
4246
+ if (!state->threaded)
4247
+ {
4248
+ for (ddata = (struct dwarf_data *) state->fileline_data;
4249
+ ddata != NULL;
4250
+ ddata = ddata->next)
4251
+ {
4252
+ ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
4253
+ data, &found);
4254
+ if (ret != 0 || found)
4255
+ return ret;
4256
+ }
4257
+ }
4258
+ else
4259
+ {
4260
+ struct dwarf_data **pp;
4261
+
4262
+ pp = (struct dwarf_data **) (void *) &state->fileline_data;
4263
+ while (1)
4264
+ {
4265
+ ddata = backtrace_atomic_load_pointer (pp);
4266
+ if (ddata == NULL)
4267
+ break;
4268
+
4269
+ ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
4270
+ data, &found);
4271
+ if (ret != 0 || found)
4272
+ return ret;
4273
+
4274
+ pp = &ddata->next;
4275
+ }
4276
+ }
4277
+
4278
+ /* FIXME: See if any libraries have been dlopen'ed. */
4279
+
4280
+ return callback (data, pc, NULL, 0, NULL);
4281
+ }
4282
+
4283
+ /* Initialize our data structures from the DWARF debug info for a
4284
+ file. Return NULL on failure. */
4285
+
4286
+ static struct dwarf_data *
4287
+ build_dwarf_data (struct backtrace_state *state,
4288
+ uintptr_t base_address,
4289
+ const struct dwarf_sections *dwarf_sections,
4290
+ int is_bigendian,
4291
+ struct dwarf_data *altlink,
4292
+ backtrace_error_callback error_callback,
4293
+ void *data)
4294
+ {
4295
+ struct unit_addrs_vector addrs_vec;
4296
+ struct unit_addrs *addrs;
4297
+ size_t addrs_count;
4298
+ struct unit_vector units_vec;
4299
+ struct unit **units;
4300
+ size_t units_count;
4301
+ struct dwarf_data *fdata;
4302
+
4303
+ if (!build_address_map (state, base_address, dwarf_sections, is_bigendian,
4304
+ altlink, error_callback, data, &addrs_vec,
4305
+ &units_vec))
4306
+ return NULL;
4307
+
4308
+ if (!backtrace_vector_release (state, &addrs_vec.vec, error_callback, data))
4309
+ return NULL;
4310
+ if (!backtrace_vector_release (state, &units_vec.vec, error_callback, data))
4311
+ return NULL;
4312
+ addrs = (struct unit_addrs *) addrs_vec.vec.base;
4313
+ units = (struct unit **) units_vec.vec.base;
4314
+ addrs_count = addrs_vec.count;
4315
+ units_count = units_vec.count;
4316
+ backtrace_qsort (addrs, addrs_count, sizeof (struct unit_addrs),
4317
+ unit_addrs_compare);
4318
+ /* No qsort for units required, already sorted. */
4319
+
4320
+ fdata = ((struct dwarf_data *)
4321
+ backtrace_alloc (state, sizeof (struct dwarf_data),
4322
+ error_callback, data));
4323
+ if (fdata == NULL)
4324
+ return NULL;
4325
+
4326
+ fdata->next = NULL;
4327
+ fdata->altlink = altlink;
4328
+ fdata->base_address = base_address;
4329
+ fdata->addrs = addrs;
4330
+ fdata->addrs_count = addrs_count;
4331
+ fdata->units = units;
4332
+ fdata->units_count = units_count;
4333
+ fdata->dwarf_sections = *dwarf_sections;
4334
+ fdata->is_bigendian = is_bigendian;
4335
+ memset (&fdata->fvec, 0, sizeof fdata->fvec);
4336
+
4337
+ return fdata;
4338
+ }
4339
+
4340
+ /* Build our data structures from the DWARF sections for a module.
4341
+ Set FILELINE_FN and STATE->FILELINE_DATA. Return 1 on success, 0
4342
+ on failure. */
4343
+
4344
+ int
4345
+ backtrace_dwarf_add (struct backtrace_state *state,
4346
+ uintptr_t base_address,
4347
+ const struct dwarf_sections *dwarf_sections,
4348
+ int is_bigendian,
4349
+ struct dwarf_data *fileline_altlink,
4350
+ backtrace_error_callback error_callback,
4351
+ void *data, fileline *fileline_fn,
4352
+ struct dwarf_data **fileline_entry)
4353
+ {
4354
+ struct dwarf_data *fdata;
4355
+
4356
+ fdata = build_dwarf_data (state, base_address, dwarf_sections, is_bigendian,
4357
+ fileline_altlink, error_callback, data);
4358
+ if (fdata == NULL)
4359
+ return 0;
4360
+
4361
+ if (fileline_entry != NULL)
4362
+ *fileline_entry = fdata;
4363
+
4364
+ if (!state->threaded)
4365
+ {
4366
+ struct dwarf_data **pp;
4367
+
4368
+ for (pp = (struct dwarf_data **) (void *) &state->fileline_data;
4369
+ *pp != NULL;
4370
+ pp = &(*pp)->next)
4371
+ ;
4372
+ *pp = fdata;
4373
+ }
4374
+ else
4375
+ {
4376
+ while (1)
4377
+ {
4378
+ struct dwarf_data **pp;
4379
+
4380
+ pp = (struct dwarf_data **) (void *) &state->fileline_data;
4381
+
4382
+ while (1)
4383
+ {
4384
+ struct dwarf_data *p;
4385
+
4386
+ p = backtrace_atomic_load_pointer (pp);
4387
+
4388
+ if (p == NULL)
4389
+ break;
4390
+
4391
+ pp = &p->next;
4392
+ }
4393
+
4394
+ if (__sync_bool_compare_and_swap (pp, NULL, fdata))
4395
+ break;
4396
+ }
4397
+ }
4398
+
4399
+ *fileline_fn = dwarf_fileline;
4400
+
4401
+ return 1;
4402
+ }