|
1 # HG changeset patch |
|
2 # User Ted Mielczarek <ted.mielczarek@gmail.com> |
|
3 # Date 1360255134 18000 |
|
4 # Thu Feb 07 11:38:54 2013 -0500 |
|
5 # Node ID 79cecfef3c2a10d719fe1af9fae2e5257109b028 |
|
6 # Parent 08f184a7e6d6d15ecc20abd56bc4e36669c0c68a |
|
7 Rework PostfixEvaluator to use a UniqueString type |
|
8 Patch by Julian Seward <jseward@acm.org>, R=ted |
|
9 |
|
10 diff --git a/Makefile.am b/Makefile.am |
|
11 --- a/Makefile.am |
|
12 +++ b/Makefile.am |
|
13 @@ -134,16 +134,17 @@ |
|
14 src/google_breakpad/processor/source_line_resolver_interface.h \ |
|
15 src/google_breakpad/processor/stack_frame.h \ |
|
16 src/google_breakpad/processor/stack_frame_cpu.h \ |
|
17 src/google_breakpad/processor/stack_frame_symbolizer.h \ |
|
18 src/google_breakpad/processor/stackwalker.h \ |
|
19 src/google_breakpad/processor/symbol_supplier.h \ |
|
20 src/google_breakpad/processor/system_info.h \ |
|
21 src/common/module.cc \ |
|
22 + src/common/unique_string.cc \ |
|
23 src/processor/address_map-inl.h \ |
|
24 src/processor/address_map.h \ |
|
25 src/processor/basic_code_module.h \ |
|
26 src/processor/basic_code_modules.cc \ |
|
27 src/processor/basic_code_modules.h \ |
|
28 src/processor/basic_source_line_resolver_types.h \ |
|
29 src/processor/basic_source_line_resolver.cc \ |
|
30 src/processor/binarystream.h \ |
|
31 @@ -430,16 +431,17 @@ |
|
32 src_tools_linux_dump_syms_dump_syms_SOURCES = \ |
|
33 src/common/dwarf_cfi_to_module.cc \ |
|
34 src/common/dwarf_cu_to_module.cc \ |
|
35 src/common/dwarf_line_to_module.cc \ |
|
36 src/common/language.cc \ |
|
37 src/common/module.cc \ |
|
38 src/common/stabs_reader.cc \ |
|
39 src/common/stabs_to_module.cc \ |
|
40 + src/common/unique_string.cc \ |
|
41 src/common/dwarf/bytereader.cc \ |
|
42 src/common/dwarf/dwarf2diehandler.cc \ |
|
43 src/common/dwarf/dwarf2reader.cc \ |
|
44 src/common/linux/dump_symbols.cc \ |
|
45 src/common/linux/elf_symbols_to_module.cc \ |
|
46 src/common/linux/elfutils.cc \ |
|
47 src/common/linux/file_id.cc \ |
|
48 src/common/linux/linux_libc_support.cc \ |
|
49 @@ -473,16 +475,17 @@ |
|
50 src/common/memory_range_unittest.cc \ |
|
51 src/common/module.cc \ |
|
52 src/common/module_unittest.cc \ |
|
53 src/common/stabs_reader.cc \ |
|
54 src/common/stabs_reader_unittest.cc \ |
|
55 src/common/stabs_to_module.cc \ |
|
56 src/common/stabs_to_module_unittest.cc \ |
|
57 src/common/test_assembler.cc \ |
|
58 + src/common/unique_string.cc \ |
|
59 src/common/dwarf/bytereader.cc \ |
|
60 src/common/dwarf/bytereader_unittest.cc \ |
|
61 src/common/dwarf/cfi_assembler.cc \ |
|
62 src/common/dwarf/dwarf2diehandler.cc \ |
|
63 src/common/dwarf/dwarf2diehandler_unittest.cc \ |
|
64 src/common/dwarf/dwarf2reader.cc \ |
|
65 src/common/dwarf/dwarf2reader_cfi_unittest.cc \ |
|
66 src/common/dwarf/dwarf2reader_die_unittest.cc \ |
|
67 @@ -561,31 +564,33 @@ |
|
68 src_processor_basic_source_line_resolver_unittest_CPPFLAGS = \ |
|
69 -I$(top_srcdir)/src \ |
|
70 -I$(top_srcdir)/src/testing/include \ |
|
71 -I$(top_srcdir)/src/testing/gtest/include \ |
|
72 -I$(top_srcdir)/src/testing/gtest \ |
|
73 -I$(top_srcdir)/src/testing |
|
74 src_processor_basic_source_line_resolver_unittest_LDADD = \ |
|
75 src/common/module.o \ |
|
76 + src/common/unique_string.o \ |
|
77 src/processor/basic_source_line_resolver.o \ |
|
78 src/processor/cfi_frame_info.o \ |
|
79 src/processor/pathname_stripper.o \ |
|
80 src/processor/logging.o \ |
|
81 src/processor/source_line_resolver_base.o \ |
|
82 src/processor/tokenize.o \ |
|
83 $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
|
84 |
|
85 src_processor_cfi_frame_info_unittest_SOURCES = \ |
|
86 src/processor/cfi_frame_info_unittest.cc \ |
|
87 src/testing/gtest/src/gtest-all.cc \ |
|
88 src/testing/gtest/src/gtest_main.cc \ |
|
89 src/testing/src/gmock-all.cc |
|
90 src_processor_cfi_frame_info_unittest_LDADD = \ |
|
91 src/common/module.o \ |
|
92 + src/common/unique_string.o \ |
|
93 src/processor/cfi_frame_info.o \ |
|
94 src/processor/logging.o \ |
|
95 src/processor/pathname_stripper.o \ |
|
96 $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
|
97 src_processor_cfi_frame_info_unittest_CPPFLAGS = \ |
|
98 -I$(top_srcdir)/src \ |
|
99 -I$(top_srcdir)/src/testing/include \ |
|
100 -I$(top_srcdir)/src/testing/gtest/include \ |
|
101 @@ -606,16 +611,17 @@ |
|
102 src_processor_exploitability_unittest_CPPFLAGS = \ |
|
103 -I$(top_srcdir)/src \ |
|
104 -I$(top_srcdir)/src/testing/include \ |
|
105 -I$(top_srcdir)/src/testing/gtest/include \ |
|
106 -I$(top_srcdir)/src/testing/gtest \ |
|
107 -I$(top_srcdir)/src/testing |
|
108 src_processor_exploitability_unittest_LDADD = \ |
|
109 src/common/module.o \ |
|
110 + src/common/unique_string.o \ |
|
111 src/processor/minidump_processor.o \ |
|
112 src/processor/process_state.o \ |
|
113 src/processor/disassembler_x86.o \ |
|
114 src/processor/exploitability.o \ |
|
115 src/processor/exploitability_win.o \ |
|
116 src/processor/basic_code_modules.o \ |
|
117 src/processor/basic_source_line_resolver.o \ |
|
118 src/processor/call_stack.o \ |
|
119 @@ -659,16 +665,17 @@ |
|
120 src_processor_fast_source_line_resolver_unittest_CPPFLAGS = \ |
|
121 -I$(top_srcdir)/src \ |
|
122 -I$(top_srcdir)/src/testing/include \ |
|
123 -I$(top_srcdir)/src/testing/gtest/include \ |
|
124 -I$(top_srcdir)/src/testing/gtest \ |
|
125 -I$(top_srcdir)/src/testing |
|
126 src_processor_fast_source_line_resolver_unittest_LDADD = \ |
|
127 src/common/module.o \ |
|
128 + src/common/unique_string.o \ |
|
129 src/processor/fast_source_line_resolver.o \ |
|
130 src/processor/basic_source_line_resolver.o \ |
|
131 src/processor/cfi_frame_info.o \ |
|
132 src/processor/module_comparer.o \ |
|
133 src/processor/module_serializer.o \ |
|
134 src/processor/pathname_stripper.o \ |
|
135 src/processor/logging.o \ |
|
136 src/processor/source_line_resolver_base.o \ |
|
137 @@ -697,16 +704,17 @@ |
|
138 src_processor_minidump_processor_unittest_CPPFLAGS = \ |
|
139 -I$(top_srcdir)/src \ |
|
140 -I$(top_srcdir)/src/testing/include \ |
|
141 -I$(top_srcdir)/src/testing/gtest/include \ |
|
142 -I$(top_srcdir)/src/testing/gtest \ |
|
143 -I$(top_srcdir)/src/testing |
|
144 src_processor_minidump_processor_unittest_LDADD = \ |
|
145 src/common/module.o \ |
|
146 + src/common/unique_string.o \ |
|
147 src/processor/basic_code_modules.o \ |
|
148 src/processor/basic_source_line_resolver.o \ |
|
149 src/processor/call_stack.o \ |
|
150 src/processor/cfi_frame_info.o \ |
|
151 src/processor/disassembler_x86.o \ |
|
152 src/processor/exploitability.o \ |
|
153 src/processor/exploitability_win.o \ |
|
154 src/processor/logging.o \ |
|
155 @@ -812,16 +820,17 @@ |
|
156 src_processor_pathname_stripper_unittest_LDADD = \ |
|
157 src/processor/pathname_stripper.o \ |
|
158 $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
|
159 |
|
160 src_processor_postfix_evaluator_unittest_SOURCES = \ |
|
161 src/processor/postfix_evaluator_unittest.cc |
|
162 src_processor_postfix_evaluator_unittest_LDADD = \ |
|
163 src/common/module.o \ |
|
164 + src/common/unique_string.o \ |
|
165 src/processor/logging.o \ |
|
166 src/processor/pathname_stripper.o \ |
|
167 $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
|
168 |
|
169 src_processor_range_map_unittest_SOURCES = \ |
|
170 src/processor/range_map_unittest.cc |
|
171 src_processor_range_map_unittest_LDADD = \ |
|
172 src/processor/logging.o \ |
|
173 @@ -943,16 +952,17 @@ |
|
174 src/processor/logging.o \ |
|
175 src/processor/minidump.o \ |
|
176 src/processor/pathname_stripper.o |
|
177 |
|
178 src_processor_minidump_stackwalk_SOURCES = \ |
|
179 src/processor/minidump_stackwalk.cc |
|
180 src_processor_minidump_stackwalk_LDADD = \ |
|
181 src/common/module.o \ |
|
182 + src/common/unique_string.o \ |
|
183 src/processor/basic_code_modules.o \ |
|
184 src/processor/basic_source_line_resolver.o \ |
|
185 src/processor/binarystream.o \ |
|
186 src/processor/call_stack.o \ |
|
187 src/processor/cfi_frame_info.o \ |
|
188 src/processor/disassembler_x86.o \ |
|
189 src/processor/exploitability.o \ |
|
190 src/processor/exploitability_win.o \ |
|
191 diff --git a/Makefile.in b/Makefile.in |
|
192 --- a/Makefile.in |
|
193 +++ b/Makefile.in |
|
194 @@ -267,18 +267,19 @@ |
|
195 src/google_breakpad/processor/source_line_resolver_base.h \ |
|
196 src/google_breakpad/processor/source_line_resolver_interface.h \ |
|
197 src/google_breakpad/processor/stack_frame.h \ |
|
198 src/google_breakpad/processor/stack_frame_cpu.h \ |
|
199 src/google_breakpad/processor/stack_frame_symbolizer.h \ |
|
200 src/google_breakpad/processor/stackwalker.h \ |
|
201 src/google_breakpad/processor/symbol_supplier.h \ |
|
202 src/google_breakpad/processor/system_info.h \ |
|
203 - src/common/module.cc src/processor/address_map-inl.h \ |
|
204 - src/processor/address_map.h src/processor/basic_code_module.h \ |
|
205 + src/common/module.cc src/common/unique_string.cc \ |
|
206 + src/processor/address_map-inl.h src/processor/address_map.h \ |
|
207 + src/processor/basic_code_module.h \ |
|
208 src/processor/basic_code_modules.cc \ |
|
209 src/processor/basic_code_modules.h \ |
|
210 src/processor/basic_source_line_resolver_types.h \ |
|
211 src/processor/basic_source_line_resolver.cc \ |
|
212 src/processor/binarystream.h src/processor/binarystream.cc \ |
|
213 src/processor/call_stack.cc src/processor/cfi_frame_info.cc \ |
|
214 src/processor/cfi_frame_info.h \ |
|
215 src/processor/contained_range_map-inl.h \ |
|
216 @@ -332,16 +333,17 @@ |
|
217 src/processor/static_map_iterator-inl.h \ |
|
218 src/processor/static_map_iterator.h \ |
|
219 src/processor/static_map-inl.h src/processor/static_map.h \ |
|
220 src/processor/static_range_map-inl.h \ |
|
221 src/processor/static_range_map.h src/processor/tokenize.cc \ |
|
222 src/processor/tokenize.h |
|
223 @DISABLE_PROCESSOR_FALSE@am_src_libbreakpad_a_OBJECTS = \ |
|
224 @DISABLE_PROCESSOR_FALSE@ src/common/module.$(OBJEXT) \ |
|
225 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.$(OBJEXT) \ |
|
226 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_code_modules.$(OBJEXT) \ |
|
227 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.$(OBJEXT) \ |
|
228 @DISABLE_PROCESSOR_FALSE@ src/processor/binarystream.$(OBJEXT) \ |
|
229 @DISABLE_PROCESSOR_FALSE@ src/processor/call_stack.$(OBJEXT) \ |
|
230 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.$(OBJEXT) \ |
|
231 @DISABLE_PROCESSOR_FALSE@ src/processor/disassembler_x86.$(OBJEXT) \ |
|
232 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability.$(OBJEXT) \ |
|
233 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_win.$(OBJEXT) \ |
|
234 @@ -525,17 +527,18 @@ |
|
235 src/common/dwarf_cu_to_module_unittest.cc \ |
|
236 src/common/dwarf_line_to_module.cc \ |
|
237 src/common/dwarf_line_to_module_unittest.cc \ |
|
238 src/common/language.cc src/common/memory_range_unittest.cc \ |
|
239 src/common/module.cc src/common/module_unittest.cc \ |
|
240 src/common/stabs_reader.cc src/common/stabs_reader_unittest.cc \ |
|
241 src/common/stabs_to_module.cc \ |
|
242 src/common/stabs_to_module_unittest.cc \ |
|
243 - src/common/test_assembler.cc src/common/dwarf/bytereader.cc \ |
|
244 + src/common/test_assembler.cc src/common/unique_string.cc \ |
|
245 + src/common/dwarf/bytereader.cc \ |
|
246 src/common/dwarf/bytereader_unittest.cc \ |
|
247 src/common/dwarf/cfi_assembler.cc \ |
|
248 src/common/dwarf/dwarf2diehandler.cc \ |
|
249 src/common/dwarf/dwarf2diehandler_unittest.cc \ |
|
250 src/common/dwarf/dwarf2reader.cc \ |
|
251 src/common/dwarf/dwarf2reader_cfi_unittest.cc \ |
|
252 src/common/dwarf/dwarf2reader_die_unittest.cc \ |
|
253 src/common/linux/dump_symbols.cc \ |
|
254 @@ -569,16 +572,17 @@ |
|
255 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-memory_range_unittest.$(OBJEXT) \ |
|
256 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-module.$(OBJEXT) \ |
|
257 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-module_unittest.$(OBJEXT) \ |
|
258 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-stabs_reader.$(OBJEXT) \ |
|
259 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-stabs_reader_unittest.$(OBJEXT) \ |
|
260 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-stabs_to_module.$(OBJEXT) \ |
|
261 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-stabs_to_module_unittest.$(OBJEXT) \ |
|
262 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-test_assembler.$(OBJEXT) \ |
|
263 +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-unique_string.$(OBJEXT) \ |
|
264 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-bytereader.$(OBJEXT) \ |
|
265 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-bytereader_unittest.$(OBJEXT) \ |
|
266 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-cfi_assembler.$(OBJEXT) \ |
|
267 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2diehandler.$(OBJEXT) \ |
|
268 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2diehandler_unittest.$(OBJEXT) \ |
|
269 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader.$(OBJEXT) \ |
|
270 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader_cfi_unittest.$(OBJEXT) \ |
|
271 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.$(OBJEXT) \ |
|
272 @@ -637,16 +641,17 @@ |
|
273 src/testing/gtest/src/gtest-all.cc \ |
|
274 src/testing/src/gmock-all.cc |
|
275 @DISABLE_PROCESSOR_FALSE@am_src_processor_basic_source_line_resolver_unittest_OBJECTS = src/processor/src_processor_basic_source_line_resolver_unittest-basic_source_line_resolver_unittest.$(OBJEXT) \ |
|
276 @DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/src_processor_basic_source_line_resolver_unittest-gtest-all.$(OBJEXT) \ |
|
277 @DISABLE_PROCESSOR_FALSE@ src/testing/src/src_processor_basic_source_line_resolver_unittest-gmock-all.$(OBJEXT) |
|
278 src_processor_basic_source_line_resolver_unittest_OBJECTS = $(am_src_processor_basic_source_line_resolver_unittest_OBJECTS) |
|
279 @DISABLE_PROCESSOR_FALSE@src_processor_basic_source_line_resolver_unittest_DEPENDENCIES = \ |
|
280 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
281 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
282 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \ |
|
283 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \ |
|
284 @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ |
|
285 @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ |
|
286 @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ |
|
287 @DISABLE_PROCESSOR_FALSE@ src/processor/tokenize.o \ |
|
288 @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) \ |
|
289 @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) |
|
290 @@ -671,16 +676,17 @@ |
|
291 @DISABLE_PROCESSOR_FALSE@am_src_processor_cfi_frame_info_unittest_OBJECTS = src/processor/src_processor_cfi_frame_info_unittest-cfi_frame_info_unittest.$(OBJEXT) \ |
|
292 @DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/src_processor_cfi_frame_info_unittest-gtest-all.$(OBJEXT) \ |
|
293 @DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/src_processor_cfi_frame_info_unittest-gtest_main.$(OBJEXT) \ |
|
294 @DISABLE_PROCESSOR_FALSE@ src/testing/src/src_processor_cfi_frame_info_unittest-gmock-all.$(OBJEXT) |
|
295 src_processor_cfi_frame_info_unittest_OBJECTS = \ |
|
296 $(am_src_processor_cfi_frame_info_unittest_OBJECTS) |
|
297 @DISABLE_PROCESSOR_FALSE@src_processor_cfi_frame_info_unittest_DEPENDENCIES = \ |
|
298 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
299 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
300 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \ |
|
301 @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ |
|
302 @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ |
|
303 @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) \ |
|
304 @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) |
|
305 am__src_processor_contained_range_map_unittest_SOURCES_DIST = \ |
|
306 src/processor/contained_range_map_unittest.cc |
|
307 @DISABLE_PROCESSOR_FALSE@am_src_processor_contained_range_map_unittest_OBJECTS = src/processor/contained_range_map_unittest.$(OBJEXT) |
|
308 @@ -713,16 +719,17 @@ |
|
309 @DISABLE_PROCESSOR_FALSE@am_src_processor_exploitability_unittest_OBJECTS = src/processor/src_processor_exploitability_unittest-exploitability_unittest.$(OBJEXT) \ |
|
310 @DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/src_processor_exploitability_unittest-gtest-all.$(OBJEXT) \ |
|
311 @DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/src_processor_exploitability_unittest-gtest_main.$(OBJEXT) \ |
|
312 @DISABLE_PROCESSOR_FALSE@ src/testing/src/src_processor_exploitability_unittest-gmock-all.$(OBJEXT) |
|
313 src_processor_exploitability_unittest_OBJECTS = \ |
|
314 $(am_src_processor_exploitability_unittest_OBJECTS) |
|
315 @DISABLE_PROCESSOR_FALSE@src_processor_exploitability_unittest_DEPENDENCIES = \ |
|
316 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
317 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
318 @DISABLE_PROCESSOR_FALSE@ src/processor/minidump_processor.o \ |
|
319 @DISABLE_PROCESSOR_FALSE@ src/processor/process_state.o \ |
|
320 @DISABLE_PROCESSOR_FALSE@ src/processor/disassembler_x86.o \ |
|
321 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability.o \ |
|
322 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_win.o \ |
|
323 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_code_modules.o \ |
|
324 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \ |
|
325 @DISABLE_PROCESSOR_FALSE@ src/processor/call_stack.o \ |
|
326 @@ -748,16 +755,17 @@ |
|
327 src/testing/gtest/src/gtest-all.cc \ |
|
328 src/testing/src/gmock-all.cc |
|
329 @DISABLE_PROCESSOR_FALSE@am_src_processor_fast_source_line_resolver_unittest_OBJECTS = src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.$(OBJEXT) \ |
|
330 @DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.$(OBJEXT) \ |
|
331 @DISABLE_PROCESSOR_FALSE@ src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.$(OBJEXT) |
|
332 src_processor_fast_source_line_resolver_unittest_OBJECTS = $(am_src_processor_fast_source_line_resolver_unittest_OBJECTS) |
|
333 @DISABLE_PROCESSOR_FALSE@src_processor_fast_source_line_resolver_unittest_DEPENDENCIES = \ |
|
334 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
335 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
336 @DISABLE_PROCESSOR_FALSE@ src/processor/fast_source_line_resolver.o \ |
|
337 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \ |
|
338 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \ |
|
339 @DISABLE_PROCESSOR_FALSE@ src/processor/module_comparer.o \ |
|
340 @DISABLE_PROCESSOR_FALSE@ src/processor/module_serializer.o \ |
|
341 @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ |
|
342 @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ |
|
343 @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ |
|
344 @@ -794,16 +802,17 @@ |
|
345 src/testing/src/gmock-all.cc |
|
346 @DISABLE_PROCESSOR_FALSE@am_src_processor_minidump_processor_unittest_OBJECTS = src/processor/src_processor_minidump_processor_unittest-minidump_processor_unittest.$(OBJEXT) \ |
|
347 @DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/src_processor_minidump_processor_unittest-gtest-all.$(OBJEXT) \ |
|
348 @DISABLE_PROCESSOR_FALSE@ src/testing/src/src_processor_minidump_processor_unittest-gmock-all.$(OBJEXT) |
|
349 src_processor_minidump_processor_unittest_OBJECTS = \ |
|
350 $(am_src_processor_minidump_processor_unittest_OBJECTS) |
|
351 @DISABLE_PROCESSOR_FALSE@src_processor_minidump_processor_unittest_DEPENDENCIES = \ |
|
352 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
353 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
354 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_code_modules.o \ |
|
355 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \ |
|
356 @DISABLE_PROCESSOR_FALSE@ src/processor/call_stack.o \ |
|
357 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \ |
|
358 @DISABLE_PROCESSOR_FALSE@ src/processor/disassembler_x86.o \ |
|
359 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability.o \ |
|
360 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_win.o \ |
|
361 @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ |
|
362 @@ -826,16 +835,17 @@ |
|
363 @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) |
|
364 am__src_processor_minidump_stackwalk_SOURCES_DIST = \ |
|
365 src/processor/minidump_stackwalk.cc |
|
366 @DISABLE_PROCESSOR_FALSE@am_src_processor_minidump_stackwalk_OBJECTS = src/processor/minidump_stackwalk.$(OBJEXT) |
|
367 src_processor_minidump_stackwalk_OBJECTS = \ |
|
368 $(am_src_processor_minidump_stackwalk_OBJECTS) |
|
369 @DISABLE_PROCESSOR_FALSE@src_processor_minidump_stackwalk_DEPENDENCIES = \ |
|
370 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
371 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
372 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_code_modules.o \ |
|
373 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \ |
|
374 @DISABLE_PROCESSOR_FALSE@ src/processor/binarystream.o \ |
|
375 @DISABLE_PROCESSOR_FALSE@ src/processor/call_stack.o \ |
|
376 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \ |
|
377 @DISABLE_PROCESSOR_FALSE@ src/processor/disassembler_x86.o \ |
|
378 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability.o \ |
|
379 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_win.o \ |
|
380 @@ -889,16 +899,17 @@ |
|
381 @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) |
|
382 am__src_processor_postfix_evaluator_unittest_SOURCES_DIST = \ |
|
383 src/processor/postfix_evaluator_unittest.cc |
|
384 @DISABLE_PROCESSOR_FALSE@am_src_processor_postfix_evaluator_unittest_OBJECTS = src/processor/postfix_evaluator_unittest.$(OBJEXT) |
|
385 src_processor_postfix_evaluator_unittest_OBJECTS = \ |
|
386 $(am_src_processor_postfix_evaluator_unittest_OBJECTS) |
|
387 @DISABLE_PROCESSOR_FALSE@src_processor_postfix_evaluator_unittest_DEPENDENCIES = \ |
|
388 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
389 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
390 @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ |
|
391 @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ |
|
392 @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) \ |
|
393 @DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) |
|
394 am__src_processor_range_map_unittest_SOURCES_DIST = \ |
|
395 src/processor/range_map_unittest.cc |
|
396 @DISABLE_PROCESSOR_FALSE@am_src_processor_range_map_unittest_OBJECTS = src/processor/range_map_unittest.$(OBJEXT) |
|
397 src_processor_range_map_unittest_OBJECTS = \ |
|
398 @@ -1069,33 +1080,35 @@ |
|
399 src_tools_linux_core2md_core2md_OBJECTS = \ |
|
400 $(am_src_tools_linux_core2md_core2md_OBJECTS) |
|
401 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@src_tools_linux_core2md_core2md_DEPENDENCIES = src/client/linux/libbreakpad_client.a |
|
402 am__src_tools_linux_dump_syms_dump_syms_SOURCES_DIST = \ |
|
403 src/common/dwarf_cfi_to_module.cc \ |
|
404 src/common/dwarf_cu_to_module.cc \ |
|
405 src/common/dwarf_line_to_module.cc src/common/language.cc \ |
|
406 src/common/module.cc src/common/stabs_reader.cc \ |
|
407 - src/common/stabs_to_module.cc src/common/dwarf/bytereader.cc \ |
|
408 + src/common/stabs_to_module.cc src/common/unique_string.cc \ |
|
409 + src/common/dwarf/bytereader.cc \ |
|
410 src/common/dwarf/dwarf2diehandler.cc \ |
|
411 src/common/dwarf/dwarf2reader.cc \ |
|
412 src/common/linux/dump_symbols.cc \ |
|
413 src/common/linux/elf_symbols_to_module.cc \ |
|
414 src/common/linux/elfutils.cc src/common/linux/file_id.cc \ |
|
415 src/common/linux/linux_libc_support.cc \ |
|
416 src/common/linux/memory_mapped_file.cc \ |
|
417 src/common/linux/safe_readlink.cc \ |
|
418 src/tools/linux/dump_syms/dump_syms.cc |
|
419 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@am_src_tools_linux_dump_syms_dump_syms_OBJECTS = src/common/dwarf_cfi_to_module.$(OBJEXT) \ |
|
420 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf_cu_to_module.$(OBJEXT) \ |
|
421 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf_line_to_module.$(OBJEXT) \ |
|
422 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/language.$(OBJEXT) \ |
|
423 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/module.$(OBJEXT) \ |
|
424 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/stabs_reader.$(OBJEXT) \ |
|
425 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/stabs_to_module.$(OBJEXT) \ |
|
426 +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/unique_string.$(OBJEXT) \ |
|
427 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/bytereader.$(OBJEXT) \ |
|
428 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2diehandler.$(OBJEXT) \ |
|
429 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.$(OBJEXT) \ |
|
430 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols.$(OBJEXT) \ |
|
431 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_symbols_to_module.$(OBJEXT) \ |
|
432 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elfutils.$(OBJEXT) \ |
|
433 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/file_id.$(OBJEXT) \ |
|
434 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/linux_libc_support.$(OBJEXT) \ |
|
435 @@ -1416,16 +1429,17 @@ |
|
436 @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/source_line_resolver_interface.h \ |
|
437 @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/stack_frame.h \ |
|
438 @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/stack_frame_cpu.h \ |
|
439 @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/stack_frame_symbolizer.h \ |
|
440 @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/stackwalker.h \ |
|
441 @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/symbol_supplier.h \ |
|
442 @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/system_info.h \ |
|
443 @DISABLE_PROCESSOR_FALSE@ src/common/module.cc \ |
|
444 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.cc \ |
|
445 @DISABLE_PROCESSOR_FALSE@ src/processor/address_map-inl.h \ |
|
446 @DISABLE_PROCESSOR_FALSE@ src/processor/address_map.h \ |
|
447 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_code_module.h \ |
|
448 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_code_modules.cc \ |
|
449 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_code_modules.h \ |
|
450 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver_types.h \ |
|
451 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.cc \ |
|
452 @DISABLE_PROCESSOR_FALSE@ src/processor/binarystream.h \ |
|
453 @@ -1618,16 +1632,17 @@ |
|
454 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@src_tools_linux_dump_syms_dump_syms_SOURCES = \ |
|
455 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf_cfi_to_module.cc \ |
|
456 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf_cu_to_module.cc \ |
|
457 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf_line_to_module.cc \ |
|
458 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/language.cc \ |
|
459 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/module.cc \ |
|
460 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/stabs_reader.cc \ |
|
461 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/stabs_to_module.cc \ |
|
462 +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/unique_string.cc \ |
|
463 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/bytereader.cc \ |
|
464 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2diehandler.cc \ |
|
465 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.cc \ |
|
466 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols.cc \ |
|
467 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_symbols_to_module.cc \ |
|
468 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elfutils.cc \ |
|
469 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/file_id.cc \ |
|
470 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/linux_libc_support.cc \ |
|
471 @@ -1661,16 +1676,17 @@ |
|
472 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/memory_range_unittest.cc \ |
|
473 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/module.cc \ |
|
474 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/module_unittest.cc \ |
|
475 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/stabs_reader.cc \ |
|
476 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/stabs_reader_unittest.cc \ |
|
477 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/stabs_to_module.cc \ |
|
478 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/stabs_to_module_unittest.cc \ |
|
479 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/test_assembler.cc \ |
|
480 +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/unique_string.cc \ |
|
481 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/bytereader.cc \ |
|
482 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/bytereader_unittest.cc \ |
|
483 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/cfi_assembler.cc \ |
|
484 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2diehandler.cc \ |
|
485 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2diehandler_unittest.cc \ |
|
486 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.cc \ |
|
487 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader_cfi_unittest.cc \ |
|
488 @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader_die_unittest.cc \ |
|
489 @@ -1753,32 +1769,34 @@ |
|
490 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src \ |
|
491 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/include \ |
|
492 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest/include \ |
|
493 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest \ |
|
494 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing |
|
495 |
|
496 @DISABLE_PROCESSOR_FALSE@src_processor_basic_source_line_resolver_unittest_LDADD = \ |
|
497 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
498 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
499 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \ |
|
500 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \ |
|
501 @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ |
|
502 @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ |
|
503 @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ |
|
504 @DISABLE_PROCESSOR_FALSE@ src/processor/tokenize.o \ |
|
505 @DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
|
506 |
|
507 @DISABLE_PROCESSOR_FALSE@src_processor_cfi_frame_info_unittest_SOURCES = \ |
|
508 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info_unittest.cc \ |
|
509 @DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/gtest-all.cc \ |
|
510 @DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/gtest_main.cc \ |
|
511 @DISABLE_PROCESSOR_FALSE@ src/testing/src/gmock-all.cc |
|
512 |
|
513 @DISABLE_PROCESSOR_FALSE@src_processor_cfi_frame_info_unittest_LDADD = \ |
|
514 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
515 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
516 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \ |
|
517 @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ |
|
518 @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ |
|
519 @DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
|
520 |
|
521 @DISABLE_PROCESSOR_FALSE@src_processor_cfi_frame_info_unittest_CPPFLAGS = \ |
|
522 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src \ |
|
523 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/include \ |
|
524 @@ -1803,16 +1821,17 @@ |
|
525 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src \ |
|
526 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/include \ |
|
527 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest/include \ |
|
528 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest \ |
|
529 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing |
|
530 |
|
531 @DISABLE_PROCESSOR_FALSE@src_processor_exploitability_unittest_LDADD = \ |
|
532 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
533 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
534 @DISABLE_PROCESSOR_FALSE@ src/processor/minidump_processor.o \ |
|
535 @DISABLE_PROCESSOR_FALSE@ src/processor/process_state.o \ |
|
536 @DISABLE_PROCESSOR_FALSE@ src/processor/disassembler_x86.o \ |
|
537 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability.o \ |
|
538 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_win.o \ |
|
539 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_code_modules.o \ |
|
540 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \ |
|
541 @DISABLE_PROCESSOR_FALSE@ src/processor/call_stack.o \ |
|
542 @@ -1860,16 +1879,17 @@ |
|
543 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src \ |
|
544 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/include \ |
|
545 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest/include \ |
|
546 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest \ |
|
547 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing |
|
548 |
|
549 @DISABLE_PROCESSOR_FALSE@src_processor_fast_source_line_resolver_unittest_LDADD = \ |
|
550 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
551 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
552 @DISABLE_PROCESSOR_FALSE@ src/processor/fast_source_line_resolver.o \ |
|
553 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \ |
|
554 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \ |
|
555 @DISABLE_PROCESSOR_FALSE@ src/processor/module_comparer.o \ |
|
556 @DISABLE_PROCESSOR_FALSE@ src/processor/module_serializer.o \ |
|
557 @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ |
|
558 @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ |
|
559 @DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \ |
|
560 @@ -1902,16 +1922,17 @@ |
|
561 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src \ |
|
562 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/include \ |
|
563 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest/include \ |
|
564 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest \ |
|
565 @DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing |
|
566 |
|
567 @DISABLE_PROCESSOR_FALSE@src_processor_minidump_processor_unittest_LDADD = \ |
|
568 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
569 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
570 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_code_modules.o \ |
|
571 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \ |
|
572 @DISABLE_PROCESSOR_FALSE@ src/processor/call_stack.o \ |
|
573 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \ |
|
574 @DISABLE_PROCESSOR_FALSE@ src/processor/disassembler_x86.o \ |
|
575 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability.o \ |
|
576 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_win.o \ |
|
577 @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ |
|
578 @@ -2029,16 +2050,17 @@ |
|
579 @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ |
|
580 @DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
|
581 |
|
582 @DISABLE_PROCESSOR_FALSE@src_processor_postfix_evaluator_unittest_SOURCES = \ |
|
583 @DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator_unittest.cc |
|
584 |
|
585 @DISABLE_PROCESSOR_FALSE@src_processor_postfix_evaluator_unittest_LDADD = \ |
|
586 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
587 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
588 @DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \ |
|
589 @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \ |
|
590 @DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
|
591 |
|
592 @DISABLE_PROCESSOR_FALSE@src_processor_range_map_unittest_SOURCES = \ |
|
593 @DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest.cc |
|
594 |
|
595 @DISABLE_PROCESSOR_FALSE@src_processor_range_map_unittest_LDADD = \ |
|
596 @@ -2169,16 +2191,17 @@ |
|
597 @DISABLE_PROCESSOR_FALSE@ src/processor/minidump.o \ |
|
598 @DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o |
|
599 |
|
600 @DISABLE_PROCESSOR_FALSE@src_processor_minidump_stackwalk_SOURCES = \ |
|
601 @DISABLE_PROCESSOR_FALSE@ src/processor/minidump_stackwalk.cc |
|
602 |
|
603 @DISABLE_PROCESSOR_FALSE@src_processor_minidump_stackwalk_LDADD = \ |
|
604 @DISABLE_PROCESSOR_FALSE@ src/common/module.o \ |
|
605 +@DISABLE_PROCESSOR_FALSE@ src/common/unique_string.o \ |
|
606 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_code_modules.o \ |
|
607 @DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \ |
|
608 @DISABLE_PROCESSOR_FALSE@ src/processor/binarystream.o \ |
|
609 @DISABLE_PROCESSOR_FALSE@ src/processor/call_stack.o \ |
|
610 @DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \ |
|
611 @DISABLE_PROCESSOR_FALSE@ src/processor/disassembler_x86.o \ |
|
612 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability.o \ |
|
613 @DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_win.o \ |
|
614 @@ -2527,16 +2550,18 @@ |
|
615 @$(MKDIR_P) src/client/linux |
|
616 @: > src/client/linux/$(am__dirstamp) |
|
617 src/client/linux/libbreakpad_client.a: $(src_client_linux_libbreakpad_client_a_OBJECTS) $(src_client_linux_libbreakpad_client_a_DEPENDENCIES) $(EXTRA_src_client_linux_libbreakpad_client_a_DEPENDENCIES) src/client/linux/$(am__dirstamp) |
|
618 -rm -f src/client/linux/libbreakpad_client.a |
|
619 $(src_client_linux_libbreakpad_client_a_AR) src/client/linux/libbreakpad_client.a $(src_client_linux_libbreakpad_client_a_OBJECTS) $(src_client_linux_libbreakpad_client_a_LIBADD) |
|
620 $(RANLIB) src/client/linux/libbreakpad_client.a |
|
621 src/common/module.$(OBJEXT): src/common/$(am__dirstamp) \ |
|
622 src/common/$(DEPDIR)/$(am__dirstamp) |
|
623 +src/common/unique_string.$(OBJEXT): src/common/$(am__dirstamp) \ |
|
624 + src/common/$(DEPDIR)/$(am__dirstamp) |
|
625 src/processor/$(am__dirstamp): |
|
626 @$(MKDIR_P) src/processor |
|
627 @: > src/processor/$(am__dirstamp) |
|
628 src/processor/$(DEPDIR)/$(am__dirstamp): |
|
629 @$(MKDIR_P) src/processor/$(DEPDIR) |
|
630 @: > src/processor/$(DEPDIR)/$(am__dirstamp) |
|
631 src/processor/basic_code_modules.$(OBJEXT): \ |
|
632 src/processor/$(am__dirstamp) \ |
|
633 @@ -2863,16 +2888,19 @@ |
|
634 src/common/$(am__dirstamp) \ |
|
635 src/common/$(DEPDIR)/$(am__dirstamp) |
|
636 src/common/src_common_dumper_unittest-stabs_to_module_unittest.$(OBJEXT): \ |
|
637 src/common/$(am__dirstamp) \ |
|
638 src/common/$(DEPDIR)/$(am__dirstamp) |
|
639 src/common/src_common_dumper_unittest-test_assembler.$(OBJEXT): \ |
|
640 src/common/$(am__dirstamp) \ |
|
641 src/common/$(DEPDIR)/$(am__dirstamp) |
|
642 +src/common/src_common_dumper_unittest-unique_string.$(OBJEXT): \ |
|
643 + src/common/$(am__dirstamp) \ |
|
644 + src/common/$(DEPDIR)/$(am__dirstamp) |
|
645 src/common/dwarf/$(am__dirstamp): |
|
646 @$(MKDIR_P) src/common/dwarf |
|
647 @: > src/common/dwarf/$(am__dirstamp) |
|
648 src/common/dwarf/$(DEPDIR)/$(am__dirstamp): |
|
649 @$(MKDIR_P) src/common/dwarf/$(DEPDIR) |
|
650 @: > src/common/dwarf/$(DEPDIR)/$(am__dirstamp) |
|
651 src/common/dwarf/src_common_dumper_unittest-bytereader.$(OBJEXT): \ |
|
652 src/common/dwarf/$(am__dirstamp) \ |
|
653 @@ -3470,28 +3498,30 @@ |
|
654 -rm -f src/common/src_common_dumper_unittest-memory_range_unittest.$(OBJEXT) |
|
655 -rm -f src/common/src_common_dumper_unittest-module.$(OBJEXT) |
|
656 -rm -f src/common/src_common_dumper_unittest-module_unittest.$(OBJEXT) |
|
657 -rm -f src/common/src_common_dumper_unittest-stabs_reader.$(OBJEXT) |
|
658 -rm -f src/common/src_common_dumper_unittest-stabs_reader_unittest.$(OBJEXT) |
|
659 -rm -f src/common/src_common_dumper_unittest-stabs_to_module.$(OBJEXT) |
|
660 -rm -f src/common/src_common_dumper_unittest-stabs_to_module_unittest.$(OBJEXT) |
|
661 -rm -f src/common/src_common_dumper_unittest-test_assembler.$(OBJEXT) |
|
662 + -rm -f src/common/src_common_dumper_unittest-unique_string.$(OBJEXT) |
|
663 -rm -f src/common/src_common_test_assembler_unittest-test_assembler.$(OBJEXT) |
|
664 -rm -f src/common/src_common_test_assembler_unittest-test_assembler_unittest.$(OBJEXT) |
|
665 -rm -f src/common/src_processor_minidump_unittest-test_assembler.$(OBJEXT) |
|
666 -rm -f src/common/src_processor_stackwalker_amd64_unittest-test_assembler.$(OBJEXT) |
|
667 -rm -f src/common/src_processor_stackwalker_arm_unittest-test_assembler.$(OBJEXT) |
|
668 -rm -f src/common/src_processor_stackwalker_x86_unittest-test_assembler.$(OBJEXT) |
|
669 -rm -f src/common/src_processor_synth_minidump_unittest-test_assembler.$(OBJEXT) |
|
670 -rm -f src/common/stabs_reader.$(OBJEXT) |
|
671 -rm -f src/common/stabs_to_module.$(OBJEXT) |
|
672 -rm -f src/common/string_conversion.$(OBJEXT) |
|
673 -rm -f src/common/tests/src_client_linux_linux_client_unittest_shlib-file_utils.$(OBJEXT) |
|
674 -rm -f src/common/tests/src_common_dumper_unittest-file_utils.$(OBJEXT) |
|
675 + -rm -f src/common/unique_string.$(OBJEXT) |
|
676 -rm -f src/processor/address_map_unittest.$(OBJEXT) |
|
677 -rm -f src/processor/basic_code_modules.$(OBJEXT) |
|
678 -rm -f src/processor/basic_source_line_resolver.$(OBJEXT) |
|
679 -rm -f src/processor/binarystream.$(OBJEXT) |
|
680 -rm -f src/processor/call_stack.$(OBJEXT) |
|
681 -rm -f src/processor/cfi_frame_info.$(OBJEXT) |
|
682 -rm -f src/processor/contained_range_map_unittest.$(OBJEXT) |
|
683 -rm -f src/processor/disassembler_x86.$(OBJEXT) |
|
684 @@ -3663,26 +3693,28 @@ |
|
685 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-memory_range_unittest.Po@am__quote@ |
|
686 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-module.Po@am__quote@ |
|
687 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-module_unittest.Po@am__quote@ |
|
688 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-stabs_reader.Po@am__quote@ |
|
689 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-stabs_reader_unittest.Po@am__quote@ |
|
690 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-stabs_to_module.Po@am__quote@ |
|
691 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-stabs_to_module_unittest.Po@am__quote@ |
|
692 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-test_assembler.Po@am__quote@ |
|
693 +@AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-unique_string.Po@am__quote@ |
|
694 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_test_assembler_unittest-test_assembler.Po@am__quote@ |
|
695 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_test_assembler_unittest-test_assembler_unittest.Po@am__quote@ |
|
696 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_processor_minidump_unittest-test_assembler.Po@am__quote@ |
|
697 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_processor_stackwalker_amd64_unittest-test_assembler.Po@am__quote@ |
|
698 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_processor_stackwalker_arm_unittest-test_assembler.Po@am__quote@ |
|
699 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_processor_stackwalker_x86_unittest-test_assembler.Po@am__quote@ |
|
700 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_processor_synth_minidump_unittest-test_assembler.Po@am__quote@ |
|
701 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/stabs_reader.Po@am__quote@ |
|
702 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/stabs_to_module.Po@am__quote@ |
|
703 @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/string_conversion.Po@am__quote@ |
|
704 +@AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/unique_string.Po@am__quote@ |
|
705 @AMDEP_TRUE@@am__include@ @am__quote@src/common/android/$(DEPDIR)/breakpad_getcontext.Po@am__quote@ |
|
706 @AMDEP_TRUE@@am__include@ @am__quote@src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext.Po@am__quote@ |
|
707 @AMDEP_TRUE@@am__include@ @am__quote@src/common/android/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-breakpad_getcontext_unittest.Po@am__quote@ |
|
708 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/bytereader.Po@am__quote@ |
|
709 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/dwarf2diehandler.Po@am__quote@ |
|
710 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/dwarf2reader.Po@am__quote@ |
|
711 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-bytereader.Po@am__quote@ |
|
712 @AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-bytereader_unittest.Po@am__quote@ |
|
713 @@ -4474,16 +4506,30 @@ |
|
714 |
|
715 src/common/src_common_dumper_unittest-test_assembler.obj: src/common/test_assembler.cc |
|
716 @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/src_common_dumper_unittest-test_assembler.obj -MD -MP -MF src/common/$(DEPDIR)/src_common_dumper_unittest-test_assembler.Tpo -c -o src/common/src_common_dumper_unittest-test_assembler.obj `if test -f 'src/common/test_assembler.cc'; then $(CYGPATH_W) 'src/common/test_assembler.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/test_assembler.cc'; fi` |
|
717 @am__fastdepCXX_TRUE@ $(am__mv) src/common/$(DEPDIR)/src_common_dumper_unittest-test_assembler.Tpo src/common/$(DEPDIR)/src_common_dumper_unittest-test_assembler.Po |
|
718 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/test_assembler.cc' object='src/common/src_common_dumper_unittest-test_assembler.obj' libtool=no @AMDEPBACKSLASH@ |
|
719 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
720 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/src_common_dumper_unittest-test_assembler.obj `if test -f 'src/common/test_assembler.cc'; then $(CYGPATH_W) 'src/common/test_assembler.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/test_assembler.cc'; fi` |
|
721 |
|
722 +src/common/src_common_dumper_unittest-unique_string.o: src/common/unique_string.cc |
|
723 +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/src_common_dumper_unittest-unique_string.o -MD -MP -MF src/common/$(DEPDIR)/src_common_dumper_unittest-unique_string.Tpo -c -o src/common/src_common_dumper_unittest-unique_string.o `test -f 'src/common/unique_string.cc' || echo '$(srcdir)/'`src/common/unique_string.cc |
|
724 +@am__fastdepCXX_TRUE@ $(am__mv) src/common/$(DEPDIR)/src_common_dumper_unittest-unique_string.Tpo src/common/$(DEPDIR)/src_common_dumper_unittest-unique_string.Po |
|
725 +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/unique_string.cc' object='src/common/src_common_dumper_unittest-unique_string.o' libtool=no @AMDEPBACKSLASH@ |
|
726 +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
727 +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/src_common_dumper_unittest-unique_string.o `test -f 'src/common/unique_string.cc' || echo '$(srcdir)/'`src/common/unique_string.cc |
|
728 + |
|
729 +src/common/src_common_dumper_unittest-unique_string.obj: src/common/unique_string.cc |
|
730 +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/src_common_dumper_unittest-unique_string.obj -MD -MP -MF src/common/$(DEPDIR)/src_common_dumper_unittest-unique_string.Tpo -c -o src/common/src_common_dumper_unittest-unique_string.obj `if test -f 'src/common/unique_string.cc'; then $(CYGPATH_W) 'src/common/unique_string.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/unique_string.cc'; fi` |
|
731 +@am__fastdepCXX_TRUE@ $(am__mv) src/common/$(DEPDIR)/src_common_dumper_unittest-unique_string.Tpo src/common/$(DEPDIR)/src_common_dumper_unittest-unique_string.Po |
|
732 +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/unique_string.cc' object='src/common/src_common_dumper_unittest-unique_string.obj' libtool=no @AMDEPBACKSLASH@ |
|
733 +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
734 +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/src_common_dumper_unittest-unique_string.obj `if test -f 'src/common/unique_string.cc'; then $(CYGPATH_W) 'src/common/unique_string.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/unique_string.cc'; fi` |
|
735 + |
|
736 src/common/dwarf/src_common_dumper_unittest-bytereader.o: src/common/dwarf/bytereader.cc |
|
737 @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/src_common_dumper_unittest-bytereader.o -MD -MP -MF src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-bytereader.Tpo -c -o src/common/dwarf/src_common_dumper_unittest-bytereader.o `test -f 'src/common/dwarf/bytereader.cc' || echo '$(srcdir)/'`src/common/dwarf/bytereader.cc |
|
738 @am__fastdepCXX_TRUE@ $(am__mv) src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-bytereader.Tpo src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-bytereader.Po |
|
739 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/dwarf/bytereader.cc' object='src/common/dwarf/src_common_dumper_unittest-bytereader.o' libtool=no @AMDEPBACKSLASH@ |
|
740 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
741 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_common_dumper_unittest-bytereader.o `test -f 'src/common/dwarf/bytereader.cc' || echo '$(srcdir)/'`src/common/dwarf/bytereader.cc |
|
742 |
|
743 src/common/dwarf/src_common_dumper_unittest-bytereader.obj: src/common/dwarf/bytereader.cc |
|
744 diff --git a/src/common/dwarf_cfi_to_module.cc b/src/common/dwarf_cfi_to_module.cc |
|
745 --- a/src/common/dwarf_cfi_to_module.cc |
|
746 +++ b/src/common/dwarf_cfi_to_module.cc |
|
747 @@ -37,40 +37,44 @@ |
|
748 #include <sstream> |
|
749 |
|
750 #include "common/dwarf_cfi_to_module.h" |
|
751 |
|
752 namespace google_breakpad { |
|
753 |
|
754 using std::ostringstream; |
|
755 |
|
756 -vector<string> DwarfCFIToModule::RegisterNames::MakeVector( |
|
757 - const char * const *strings, |
|
758 +vector<const UniqueString*> DwarfCFIToModule::RegisterNames::MakeVector( |
|
759 + const char* const* strings, |
|
760 size_t size) { |
|
761 - vector<string> names(strings, strings + size); |
|
762 + vector<const UniqueString*> names(size, NULL); |
|
763 + for (size_t i = 0; i < size; ++i) { |
|
764 + names[i] = ToUniqueString(strings[i]); |
|
765 + } |
|
766 + |
|
767 return names; |
|
768 } |
|
769 |
|
770 -vector<string> DwarfCFIToModule::RegisterNames::I386() { |
|
771 +vector<const UniqueString*> DwarfCFIToModule::RegisterNames::I386() { |
|
772 static const char *const names[] = { |
|
773 "$eax", "$ecx", "$edx", "$ebx", "$esp", "$ebp", "$esi", "$edi", |
|
774 "$eip", "$eflags", "$unused1", |
|
775 "$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7", |
|
776 "$unused2", "$unused3", |
|
777 "$xmm0", "$xmm1", "$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7", |
|
778 "$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7", |
|
779 "$fcw", "$fsw", "$mxcsr", |
|
780 "$es", "$cs", "$ss", "$ds", "$fs", "$gs", "$unused4", "$unused5", |
|
781 "$tr", "$ldtr" |
|
782 }; |
|
783 |
|
784 return MakeVector(names, sizeof(names) / sizeof(names[0])); |
|
785 } |
|
786 |
|
787 -vector<string> DwarfCFIToModule::RegisterNames::X86_64() { |
|
788 +vector<const UniqueString*> DwarfCFIToModule::RegisterNames::X86_64() { |
|
789 static const char *const names[] = { |
|
790 "$rax", "$rdx", "$rcx", "$rbx", "$rsi", "$rdi", "$rbp", "$rsp", |
|
791 "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15", |
|
792 "$rip", |
|
793 "$xmm0","$xmm1","$xmm2", "$xmm3", "$xmm4", "$xmm5", "$xmm6", "$xmm7", |
|
794 "$xmm8","$xmm9","$xmm10","$xmm11","$xmm12","$xmm13","$xmm14","$xmm15", |
|
795 "$st0", "$st1", "$st2", "$st3", "$st4", "$st5", "$st6", "$st7", |
|
796 "$mm0", "$mm1", "$mm2", "$mm3", "$mm4", "$mm5", "$mm6", "$mm7", |
|
797 @@ -80,17 +84,17 @@ |
|
798 "$tr", "$ldtr", |
|
799 "$mxcsr", "$fcw", "$fsw" |
|
800 }; |
|
801 |
|
802 return MakeVector(names, sizeof(names) / sizeof(names[0])); |
|
803 } |
|
804 |
|
805 // Per ARM IHI 0040A, section 3.1 |
|
806 -vector<string> DwarfCFIToModule::RegisterNames::ARM() { |
|
807 +vector<const UniqueString*> DwarfCFIToModule::RegisterNames::ARM() { |
|
808 static const char *const names[] = { |
|
809 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", |
|
810 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", |
|
811 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", |
|
812 "fps", "cpsr", "", "", "", "", "", "", |
|
813 "", "", "", "", "", "", "", "", |
|
814 "", "", "", "", "", "", "", "", |
|
815 "", "", "", "", "", "", "", "", |
|
816 @@ -122,40 +126,40 @@ |
|
817 return_address_ = return_address; |
|
818 |
|
819 // Breakpad STACK CFI records must provide a .ra rule, but DWARF CFI |
|
820 // may not establish any rule for .ra if the return address column |
|
821 // is an ordinary register, and that register holds the return |
|
822 // address on entry to the function. So establish an initial .ra |
|
823 // rule citing the return address register. |
|
824 if (return_address_ < register_names_.size()) |
|
825 - entry_->initial_rules[ra_name_] |
|
826 + entry_->initial_rules[ustr__ZDra()] |
|
827 = Module::Expr(register_names_[return_address_], 0, false); |
|
828 |
|
829 return true; |
|
830 } |
|
831 |
|
832 -string DwarfCFIToModule::RegisterName(int i) { |
|
833 +const UniqueString* DwarfCFIToModule::RegisterName(int i) { |
|
834 assert(entry_); |
|
835 if (i < 0) { |
|
836 assert(i == kCFARegister); |
|
837 - return cfa_name_; |
|
838 + return ustr__ZDcfa(); |
|
839 } |
|
840 unsigned reg = i; |
|
841 if (reg == return_address_) |
|
842 - return ra_name_; |
|
843 + return ustr__ZDra(); |
|
844 |
|
845 // Ensure that a non-empty name exists for this register value. |
|
846 - if (reg < register_names_.size() && !register_names_[reg].empty()) |
|
847 + if (reg < register_names_.size() && register_names_[reg] != ustr__empty()) |
|
848 return register_names_[reg]; |
|
849 |
|
850 reporter_->UnnamedRegister(entry_offset_, reg); |
|
851 char buf[30]; |
|
852 sprintf(buf, "unnamed_register%u", reg); |
|
853 - return buf; |
|
854 + return ToUniqueString(buf); |
|
855 } |
|
856 |
|
857 void DwarfCFIToModule::Record(Module::Address address, int reg, |
|
858 const Module::Expr &rule) { |
|
859 assert(entry_); |
|
860 |
|
861 // Is this one of this entry's initial rules? |
|
862 if (address == entry_->address) |
|
863 @@ -228,28 +232,30 @@ |
|
864 |
|
865 void DwarfCFIToModule::Reporter::UnnamedRegister(size_t offset, int reg) { |
|
866 fprintf(stderr, "%s, section '%s': " |
|
867 "the call frame entry at offset 0x%zx refers to register %d," |
|
868 " whose name we don't know\n", |
|
869 file_.c_str(), section_.c_str(), offset, reg); |
|
870 } |
|
871 |
|
872 -void DwarfCFIToModule::Reporter::UndefinedNotSupported(size_t offset, |
|
873 - const string ®) { |
|
874 +void DwarfCFIToModule::Reporter::UndefinedNotSupported( |
|
875 + size_t offset, |
|
876 + const UniqueString* reg) { |
|
877 fprintf(stderr, "%s, section '%s': " |
|
878 "the call frame entry at offset 0x%zx sets the rule for " |
|
879 "register '%s' to 'undefined', but the Breakpad symbol file format" |
|
880 " cannot express this\n", |
|
881 - file_.c_str(), section_.c_str(), offset, reg.c_str()); |
|
882 + file_.c_str(), section_.c_str(), offset, FromUniqueString(reg)); |
|
883 } |
|
884 |
|
885 -void DwarfCFIToModule::Reporter::ExpressionsNotSupported(size_t offset, |
|
886 - const string ®) { |
|
887 +void DwarfCFIToModule::Reporter::ExpressionsNotSupported( |
|
888 + size_t offset, |
|
889 + const UniqueString* reg) { |
|
890 fprintf(stderr, "%s, section '%s': " |
|
891 "the call frame entry at offset 0x%zx uses a DWARF expression to" |
|
892 " describe how to recover register '%s', " |
|
893 " but this translator cannot yet translate DWARF expressions to" |
|
894 " Breakpad postfix expressions\n", |
|
895 - file_.c_str(), section_.c_str(), offset, reg.c_str()); |
|
896 + file_.c_str(), section_.c_str(), offset, FromUniqueString(reg)); |
|
897 } |
|
898 |
|
899 } // namespace google_breakpad |
|
900 diff --git a/src/common/dwarf_cfi_to_module.h b/src/common/dwarf_cfi_to_module.h |
|
901 --- a/src/common/dwarf_cfi_to_module.h |
|
902 +++ b/src/common/dwarf_cfi_to_module.h |
|
903 @@ -44,16 +44,17 @@ |
|
904 |
|
905 #include <set> |
|
906 #include <string> |
|
907 #include <vector> |
|
908 |
|
909 #include "common/module.h" |
|
910 #include "common/dwarf/dwarf2reader.h" |
|
911 #include "common/using_std_string.h" |
|
912 +#include "common/unique_string.h" |
|
913 |
|
914 namespace google_breakpad { |
|
915 |
|
916 using dwarf2reader::CallFrameInfo; |
|
917 using google_breakpad::Module; |
|
918 using std::set; |
|
919 using std::vector; |
|
920 |
|
921 @@ -78,61 +79,65 @@ |
|
922 // The DWARF CFI entry at OFFSET cites register REG, but REG is not |
|
923 // covered by the vector of register names passed to the |
|
924 // DwarfCFIToModule constructor, nor does it match the return |
|
925 // address column number for this entry. |
|
926 virtual void UnnamedRegister(size_t offset, int reg); |
|
927 |
|
928 // The DWARF CFI entry at OFFSET says that REG is undefined, but the |
|
929 // Breakpad symbol file format cannot express this. |
|
930 - virtual void UndefinedNotSupported(size_t offset, const string ®); |
|
931 + virtual void UndefinedNotSupported(size_t offset, |
|
932 + const UniqueString* reg); |
|
933 |
|
934 // The DWARF CFI entry at OFFSET says that REG uses a DWARF |
|
935 // expression to find its value, but DwarfCFIToModule is not |
|
936 // capable of translating DWARF expressions to Breakpad postfix |
|
937 // expressions. |
|
938 - virtual void ExpressionsNotSupported(size_t offset, const string ®); |
|
939 + virtual void ExpressionsNotSupported(size_t offset, |
|
940 + const UniqueString* reg); |
|
941 |
|
942 protected: |
|
943 string file_, section_; |
|
944 }; |
|
945 |
|
946 // Register name tables. If TABLE is a vector returned by one of these |
|
947 // functions, then TABLE[R] is the name of the register numbered R in |
|
948 // DWARF call frame information. |
|
949 class RegisterNames { |
|
950 public: |
|
951 // Intel's "x86" or IA-32. |
|
952 - static vector<string> I386(); |
|
953 + static vector<const UniqueString*> I386(); |
|
954 |
|
955 // AMD x86_64, AMD64, Intel EM64T, or Intel 64 |
|
956 - static vector<string> X86_64(); |
|
957 + static vector<const UniqueString*> X86_64(); |
|
958 |
|
959 // ARM. |
|
960 - static vector<string> ARM(); |
|
961 + static vector<const UniqueString*> ARM(); |
|
962 |
|
963 private: |
|
964 // Given STRINGS, an array of C strings with SIZE elements, return an |
|
965 // equivalent vector<string>. |
|
966 - static vector<string> MakeVector(const char * const *strings, size_t size); |
|
967 + static vector<const UniqueString*> MakeVector(const char * const *strings, |
|
968 + size_t size); |
|
969 }; |
|
970 |
|
971 // Create a handler for the dwarf2reader::CallFrameInfo parser that |
|
972 // records the stack unwinding information it receives in MODULE. |
|
973 // |
|
974 // Use REGISTER_NAMES[I] as the name of register number I; *this |
|
975 // keeps a reference to the vector, so the vector should remain |
|
976 // alive for as long as the DwarfCFIToModule does. |
|
977 // |
|
978 // Use REPORTER for reporting problems encountered in the conversion |
|
979 // process. |
|
980 - DwarfCFIToModule(Module *module, const vector<string> ®ister_names, |
|
981 + DwarfCFIToModule(Module *module, |
|
982 + const vector<const UniqueString*> ®ister_names, |
|
983 Reporter *reporter) |
|
984 : module_(module), register_names_(register_names), reporter_(reporter), |
|
985 - entry_(NULL), return_address_(-1), cfa_name_(".cfa"), ra_name_(".ra") { |
|
986 + entry_(NULL), return_address_(-1) { |
|
987 } |
|
988 virtual ~DwarfCFIToModule() { delete entry_; } |
|
989 |
|
990 virtual bool Entry(size_t offset, uint64 address, uint64 length, |
|
991 uint8 version, const string &augmentation, |
|
992 unsigned return_address); |
|
993 virtual bool UndefinedRule(uint64 address, int reg); |
|
994 virtual bool SameValueRule(uint64 address, int reg); |
|
995 @@ -144,53 +149,36 @@ |
|
996 virtual bool ExpressionRule(uint64 address, int reg, |
|
997 const string &expression); |
|
998 virtual bool ValExpressionRule(uint64 address, int reg, |
|
999 const string &expression); |
|
1000 virtual bool End(); |
|
1001 |
|
1002 private: |
|
1003 // Return the name to use for register REG. |
|
1004 - string RegisterName(int i); |
|
1005 + const UniqueString* RegisterName(int i); |
|
1006 |
|
1007 // Record RULE for register REG at ADDRESS. |
|
1008 void Record(Module::Address address, int reg, const Module::Expr &rule); |
|
1009 |
|
1010 // The module to which we should add entries. |
|
1011 Module *module_; |
|
1012 |
|
1013 // Map from register numbers to register names. |
|
1014 - const vector<string> ®ister_names_; |
|
1015 + const vector<const UniqueString*> ®ister_names_; |
|
1016 |
|
1017 // The reporter to use to report problems. |
|
1018 Reporter *reporter_; |
|
1019 |
|
1020 // The current entry we're constructing. |
|
1021 Module::StackFrameEntry *entry_; |
|
1022 |
|
1023 // The section offset of the current frame description entry, for |
|
1024 // use in error messages. |
|
1025 size_t entry_offset_; |
|
1026 |
|
1027 // The return address column for that entry. |
|
1028 unsigned return_address_; |
|
1029 - |
|
1030 - // The names of the return address and canonical frame address. Putting |
|
1031 - // these here instead of using string literals allows us to share their |
|
1032 - // texts in reference-counted std::string implementations (all the |
|
1033 - // popular ones). Many, many rules cite these strings. |
|
1034 - string cfa_name_, ra_name_; |
|
1035 - |
|
1036 - // A set of strings used by this CFI. Before storing a string in one of |
|
1037 - // our data structures, insert it into this set, and then use the string |
|
1038 - // from the set. |
|
1039 - // |
|
1040 - // Because std::string uses reference counting internally, simply using |
|
1041 - // strings from this set, even if passed by value, assigned, or held |
|
1042 - // directly in structures and containers (map<string, ...>, for example), |
|
1043 - // causes those strings to share a single instance of each distinct piece |
|
1044 - // of text. |
|
1045 - set<string> common_strings_; |
|
1046 }; |
|
1047 |
|
1048 } // namespace google_breakpad |
|
1049 |
|
1050 #endif // COMMON_LINUX_DWARF_CFI_TO_MODULE_H |
|
1051 diff --git a/src/common/dwarf_cfi_to_module_unittest.cc b/src/common/dwarf_cfi_to_module_unittest.cc |
|
1052 --- a/src/common/dwarf_cfi_to_module_unittest.cc |
|
1053 +++ b/src/common/dwarf_cfi_to_module_unittest.cc |
|
1054 @@ -37,52 +37,59 @@ |
|
1055 #include "breakpad_googletest_includes.h" |
|
1056 #include "common/dwarf_cfi_to_module.h" |
|
1057 #include "common/using_std_string.h" |
|
1058 |
|
1059 using std::vector; |
|
1060 |
|
1061 using google_breakpad::Module; |
|
1062 using google_breakpad::DwarfCFIToModule; |
|
1063 +using google_breakpad::ToUniqueString; |
|
1064 +using google_breakpad::UniqueString; |
|
1065 +using google_breakpad::ustr__ZDcfa; |
|
1066 +using google_breakpad::ustr__ZDra; |
|
1067 +using google_breakpad::ustr__empty; |
|
1068 using testing::ContainerEq; |
|
1069 using testing::Test; |
|
1070 using testing::_; |
|
1071 |
|
1072 struct MockCFIReporter: public DwarfCFIToModule::Reporter { |
|
1073 MockCFIReporter(const string &file, const string §ion) |
|
1074 : Reporter(file, section) { } |
|
1075 MOCK_METHOD2(UnnamedRegister, void(size_t offset, int reg)); |
|
1076 - MOCK_METHOD2(UndefinedNotSupported, void(size_t offset, const string ®)); |
|
1077 - MOCK_METHOD2(ExpressionsNotSupported, void(size_t offset, const string ®)); |
|
1078 + MOCK_METHOD2(UndefinedNotSupported, void(size_t offset, |
|
1079 + const UniqueString* reg)); |
|
1080 + MOCK_METHOD2(ExpressionsNotSupported, void(size_t offset, |
|
1081 + const UniqueString* reg)); |
|
1082 }; |
|
1083 |
|
1084 struct DwarfCFIToModuleFixture { |
|
1085 DwarfCFIToModuleFixture() |
|
1086 : module("module name", "module os", "module arch", "module id"), |
|
1087 reporter("reporter file", "reporter section"), |
|
1088 handler(&module, register_names, &reporter) { |
|
1089 - register_names.push_back("reg0"); |
|
1090 - register_names.push_back("reg1"); |
|
1091 - register_names.push_back("reg2"); |
|
1092 - register_names.push_back("reg3"); |
|
1093 - register_names.push_back("reg4"); |
|
1094 - register_names.push_back("reg5"); |
|
1095 - register_names.push_back("reg6"); |
|
1096 - register_names.push_back("reg7"); |
|
1097 - register_names.push_back("sp"); |
|
1098 - register_names.push_back("pc"); |
|
1099 - register_names.push_back(""); |
|
1100 + register_names.push_back(ToUniqueString("reg0")); |
|
1101 + register_names.push_back(ToUniqueString("reg1")); |
|
1102 + register_names.push_back(ToUniqueString("reg2")); |
|
1103 + register_names.push_back(ToUniqueString("reg3")); |
|
1104 + register_names.push_back(ToUniqueString("reg4")); |
|
1105 + register_names.push_back(ToUniqueString("reg5")); |
|
1106 + register_names.push_back(ToUniqueString("reg6")); |
|
1107 + register_names.push_back(ToUniqueString("reg7")); |
|
1108 + register_names.push_back(ToUniqueString("sp")); |
|
1109 + register_names.push_back(ToUniqueString("pc")); |
|
1110 + register_names.push_back(ustr__empty()); |
|
1111 |
|
1112 EXPECT_CALL(reporter, UnnamedRegister(_, _)).Times(0); |
|
1113 EXPECT_CALL(reporter, UndefinedNotSupported(_, _)).Times(0); |
|
1114 EXPECT_CALL(reporter, ExpressionsNotSupported(_, _)).Times(0); |
|
1115 } |
|
1116 |
|
1117 Module module; |
|
1118 - vector<string> register_names; |
|
1119 + vector<const UniqueString*> register_names; |
|
1120 MockCFIReporter reporter; |
|
1121 DwarfCFIToModule handler; |
|
1122 vector<Module::StackFrameEntry *> entries; |
|
1123 }; |
|
1124 |
|
1125 class Entry: public DwarfCFIToModuleFixture, public Test { }; |
|
1126 |
|
1127 TEST_F(Entry, Accept) { |
|
1128 @@ -127,183 +134,190 @@ |
|
1129 } |
|
1130 uint64 entry_address, entry_size; |
|
1131 unsigned return_reg; |
|
1132 }; |
|
1133 |
|
1134 class Rule: public RuleFixture, public Test { }; |
|
1135 |
|
1136 TEST_F(Rule, UndefinedRule) { |
|
1137 - EXPECT_CALL(reporter, UndefinedNotSupported(_, "reg7")); |
|
1138 + EXPECT_CALL(reporter, UndefinedNotSupported(_, ToUniqueString("reg7"))); |
|
1139 StartEntry(); |
|
1140 ASSERT_TRUE(handler.UndefinedRule(entry_address, 7)); |
|
1141 ASSERT_TRUE(handler.End()); |
|
1142 CheckEntry(); |
|
1143 EXPECT_EQ(0U, entries[0]->initial_rules.size()); |
|
1144 EXPECT_EQ(0U, entries[0]->rule_changes.size()); |
|
1145 } |
|
1146 |
|
1147 TEST_F(Rule, RegisterWithEmptyName) { |
|
1148 EXPECT_CALL(reporter, UnnamedRegister(_, 10)); |
|
1149 - EXPECT_CALL(reporter, UndefinedNotSupported(_, "unnamed_register10")); |
|
1150 + EXPECT_CALL(reporter, |
|
1151 + UndefinedNotSupported(_, ToUniqueString("unnamed_register10"))); |
|
1152 StartEntry(); |
|
1153 ASSERT_TRUE(handler.UndefinedRule(entry_address, 10)); |
|
1154 ASSERT_TRUE(handler.End()); |
|
1155 CheckEntry(); |
|
1156 EXPECT_EQ(0U, entries[0]->initial_rules.size()); |
|
1157 EXPECT_EQ(0U, entries[0]->rule_changes.size()); |
|
1158 } |
|
1159 |
|
1160 TEST_F(Rule, SameValueRule) { |
|
1161 StartEntry(); |
|
1162 ASSERT_TRUE(handler.SameValueRule(entry_address, 6)); |
|
1163 ASSERT_TRUE(handler.End()); |
|
1164 CheckEntry(); |
|
1165 Module::RuleMap expected_initial; |
|
1166 - expected_initial["reg6"] = Module::Expr("reg6", 0, false); |
|
1167 + const UniqueString* reg6 = ToUniqueString("reg6"); |
|
1168 + expected_initial[reg6] = Module::Expr(reg6, 0, false); |
|
1169 EXPECT_THAT(entries[0]->initial_rules, ContainerEq(expected_initial)); |
|
1170 EXPECT_EQ(0U, entries[0]->rule_changes.size()); |
|
1171 } |
|
1172 |
|
1173 TEST_F(Rule, OffsetRule) { |
|
1174 StartEntry(); |
|
1175 ASSERT_TRUE(handler.OffsetRule(entry_address + 1, return_reg, |
|
1176 DwarfCFIToModule::kCFARegister, |
|
1177 16927065)); |
|
1178 ASSERT_TRUE(handler.End()); |
|
1179 CheckEntry(); |
|
1180 EXPECT_EQ(0U, entries[0]->initial_rules.size()); |
|
1181 Module::RuleChangeMap expected_changes; |
|
1182 - expected_changes[entry_address + 1][".ra"] = |
|
1183 - Module::Expr(".cfa", 16927065, true); |
|
1184 + expected_changes[entry_address + 1][ustr__ZDra()] = |
|
1185 + Module::Expr(ustr__ZDcfa(), 16927065, true); |
|
1186 EXPECT_THAT(entries[0]->rule_changes, ContainerEq(expected_changes)); |
|
1187 } |
|
1188 |
|
1189 TEST_F(Rule, OffsetRuleNegative) { |
|
1190 StartEntry(); |
|
1191 ASSERT_TRUE(handler.OffsetRule(entry_address + 1, |
|
1192 DwarfCFIToModule::kCFARegister, 4, -34530721)); |
|
1193 ASSERT_TRUE(handler.End()); |
|
1194 CheckEntry(); |
|
1195 EXPECT_EQ(0U, entries[0]->initial_rules.size()); |
|
1196 Module::RuleChangeMap expected_changes; |
|
1197 - expected_changes[entry_address + 1][".cfa"] = |
|
1198 - Module::Expr("reg4", -34530721, true); |
|
1199 + expected_changes[entry_address + 1][ustr__ZDcfa()] = |
|
1200 + Module::Expr(ToUniqueString("reg4"), -34530721, true); |
|
1201 EXPECT_THAT(entries[0]->rule_changes, ContainerEq(expected_changes)); |
|
1202 } |
|
1203 |
|
1204 TEST_F(Rule, ValOffsetRule) { |
|
1205 // Use an unnamed register number, to exercise that branch of RegisterName. |
|
1206 EXPECT_CALL(reporter, UnnamedRegister(_, 11)); |
|
1207 StartEntry(); |
|
1208 ASSERT_TRUE(handler.ValOffsetRule(entry_address + 0x5ab7, |
|
1209 DwarfCFIToModule::kCFARegister, |
|
1210 11, 61812979)); |
|
1211 ASSERT_TRUE(handler.End()); |
|
1212 CheckEntry(); |
|
1213 EXPECT_EQ(0U, entries[0]->initial_rules.size()); |
|
1214 Module::RuleChangeMap expected_changes; |
|
1215 - expected_changes[entry_address + 0x5ab7][".cfa"] = |
|
1216 - Module::Expr("unnamed_register11", 61812979, false); |
|
1217 + expected_changes[entry_address + 0x5ab7][ustr__ZDcfa()] = |
|
1218 + Module::Expr(ToUniqueString("unnamed_register11"), 61812979, false); |
|
1219 EXPECT_THAT(entries[0]->rule_changes, ContainerEq(expected_changes)); |
|
1220 } |
|
1221 |
|
1222 TEST_F(Rule, RegisterRule) { |
|
1223 StartEntry(); |
|
1224 ASSERT_TRUE(handler.RegisterRule(entry_address, return_reg, 3)); |
|
1225 ASSERT_TRUE(handler.End()); |
|
1226 CheckEntry(); |
|
1227 Module::RuleMap expected_initial; |
|
1228 - expected_initial[".ra"] = Module::Expr("reg3", 0, false); |
|
1229 + expected_initial[ustr__ZDra()] = |
|
1230 + Module::Expr(ToUniqueString("reg3"), 0, false); |
|
1231 EXPECT_THAT(entries[0]->initial_rules, ContainerEq(expected_initial)); |
|
1232 EXPECT_EQ(0U, entries[0]->rule_changes.size()); |
|
1233 } |
|
1234 |
|
1235 TEST_F(Rule, ExpressionRule) { |
|
1236 - EXPECT_CALL(reporter, ExpressionsNotSupported(_, "reg2")); |
|
1237 + EXPECT_CALL(reporter, ExpressionsNotSupported(_, ToUniqueString("reg2"))); |
|
1238 StartEntry(); |
|
1239 ASSERT_TRUE(handler.ExpressionRule(entry_address + 0xf326, 2, |
|
1240 "it takes two to tango")); |
|
1241 ASSERT_TRUE(handler.End()); |
|
1242 CheckEntry(); |
|
1243 EXPECT_EQ(0U, entries[0]->initial_rules.size()); |
|
1244 EXPECT_EQ(0U, entries[0]->rule_changes.size()); |
|
1245 } |
|
1246 |
|
1247 TEST_F(Rule, ValExpressionRule) { |
|
1248 - EXPECT_CALL(reporter, ExpressionsNotSupported(_, "reg0")); |
|
1249 + EXPECT_CALL(reporter, ExpressionsNotSupported(_, ToUniqueString("reg0"))); |
|
1250 StartEntry(); |
|
1251 ASSERT_TRUE(handler.ValExpressionRule(entry_address + 0x6367, 0, |
|
1252 "bit off more than he could chew")); |
|
1253 ASSERT_TRUE(handler.End()); |
|
1254 CheckEntry(); |
|
1255 EXPECT_EQ(0U, entries[0]->initial_rules.size()); |
|
1256 EXPECT_EQ(0U, entries[0]->rule_changes.size()); |
|
1257 } |
|
1258 |
|
1259 TEST_F(Rule, DefaultReturnAddressRule) { |
|
1260 return_reg = 2; |
|
1261 StartEntry(); |
|
1262 ASSERT_TRUE(handler.RegisterRule(entry_address, 0, 1)); |
|
1263 ASSERT_TRUE(handler.End()); |
|
1264 CheckEntry(); |
|
1265 Module::RuleMap expected_initial; |
|
1266 - expected_initial[".ra"] = Module::Expr("reg2", 0, false); |
|
1267 - expected_initial["reg0"] = Module::Expr("reg1", 0, false); |
|
1268 + expected_initial[ustr__ZDra()] = |
|
1269 + Module::Expr(ToUniqueString("reg2"), 0, false); |
|
1270 + expected_initial[ToUniqueString("reg0")] = |
|
1271 + Module::Expr(ToUniqueString("reg1"), 0, false); |
|
1272 EXPECT_THAT(entries[0]->initial_rules, ContainerEq(expected_initial)); |
|
1273 EXPECT_EQ(0U, entries[0]->rule_changes.size()); |
|
1274 } |
|
1275 |
|
1276 TEST_F(Rule, DefaultReturnAddressRuleOverride) { |
|
1277 return_reg = 2; |
|
1278 StartEntry(); |
|
1279 ASSERT_TRUE(handler.RegisterRule(entry_address, return_reg, 1)); |
|
1280 ASSERT_TRUE(handler.End()); |
|
1281 CheckEntry(); |
|
1282 Module::RuleMap expected_initial; |
|
1283 - expected_initial[".ra"] = Module::Expr("reg1", 0, false); |
|
1284 + expected_initial[ustr__ZDra()] = |
|
1285 + Module::Expr(ToUniqueString("reg1"), 0, false); |
|
1286 EXPECT_THAT(entries[0]->initial_rules, ContainerEq(expected_initial)); |
|
1287 EXPECT_EQ(0U, entries[0]->rule_changes.size()); |
|
1288 } |
|
1289 |
|
1290 TEST_F(Rule, DefaultReturnAddressRuleLater) { |
|
1291 return_reg = 2; |
|
1292 StartEntry(); |
|
1293 ASSERT_TRUE(handler.RegisterRule(entry_address + 1, return_reg, 1)); |
|
1294 ASSERT_TRUE(handler.End()); |
|
1295 CheckEntry(); |
|
1296 Module::RuleMap expected_initial; |
|
1297 - expected_initial[".ra"] = Module::Expr("reg2", 0, false); |
|
1298 + expected_initial[ustr__ZDra()] = |
|
1299 + Module::Expr(ToUniqueString("reg2"), 0, false); |
|
1300 EXPECT_THAT(entries[0]->initial_rules, ContainerEq(expected_initial)); |
|
1301 Module::RuleChangeMap expected_changes; |
|
1302 - expected_changes[entry_address + 1][".ra"] = |
|
1303 - Module::Expr("reg1", 0, false); |
|
1304 + expected_changes[entry_address + 1][ustr__ZDra()] = |
|
1305 + Module::Expr(ToUniqueString("reg1"), 0, false); |
|
1306 EXPECT_THAT(entries[0]->rule_changes, ContainerEq(expected_changes)); |
|
1307 } |
|
1308 |
|
1309 TEST(RegisterNames, I386) { |
|
1310 - vector<string> names = DwarfCFIToModule::RegisterNames::I386(); |
|
1311 + vector<const UniqueString*> names = DwarfCFIToModule::RegisterNames::I386(); |
|
1312 |
|
1313 - EXPECT_EQ("$eax", names[0]); |
|
1314 - EXPECT_EQ("$ecx", names[1]); |
|
1315 - EXPECT_EQ("$esp", names[4]); |
|
1316 - EXPECT_EQ("$eip", names[8]); |
|
1317 + EXPECT_EQ(ToUniqueString("$eax"), names[0]); |
|
1318 + EXPECT_EQ(ToUniqueString("$ecx"), names[1]); |
|
1319 + EXPECT_EQ(ToUniqueString("$esp"), names[4]); |
|
1320 + EXPECT_EQ(ToUniqueString("$eip"), names[8]); |
|
1321 } |
|
1322 |
|
1323 TEST(RegisterNames, ARM) { |
|
1324 - vector<string> names = DwarfCFIToModule::RegisterNames::ARM(); |
|
1325 + vector<const UniqueString*> names = DwarfCFIToModule::RegisterNames::ARM(); |
|
1326 |
|
1327 - EXPECT_EQ("r0", names[0]); |
|
1328 - EXPECT_EQ("r10", names[10]); |
|
1329 - EXPECT_EQ("sp", names[13]); |
|
1330 - EXPECT_EQ("lr", names[14]); |
|
1331 - EXPECT_EQ("pc", names[15]); |
|
1332 + EXPECT_EQ(ToUniqueString("r0"), names[0]); |
|
1333 + EXPECT_EQ(ToUniqueString("r10"), names[10]); |
|
1334 + EXPECT_EQ(ToUniqueString("sp"), names[13]); |
|
1335 + EXPECT_EQ(ToUniqueString("lr"), names[14]); |
|
1336 + EXPECT_EQ(ToUniqueString("pc"), names[15]); |
|
1337 } |
|
1338 |
|
1339 TEST(RegisterNames, X86_64) { |
|
1340 - vector<string> names = DwarfCFIToModule::RegisterNames::X86_64(); |
|
1341 + vector<const UniqueString*> names = DwarfCFIToModule::RegisterNames::X86_64(); |
|
1342 |
|
1343 - EXPECT_EQ("$rax", names[0]); |
|
1344 - EXPECT_EQ("$rdx", names[1]); |
|
1345 - EXPECT_EQ("$rbp", names[6]); |
|
1346 - EXPECT_EQ("$rsp", names[7]); |
|
1347 - EXPECT_EQ("$rip", names[16]); |
|
1348 + EXPECT_EQ(ToUniqueString("$rax"), names[0]); |
|
1349 + EXPECT_EQ(ToUniqueString("$rdx"), names[1]); |
|
1350 + EXPECT_EQ(ToUniqueString("$rbp"), names[6]); |
|
1351 + EXPECT_EQ(ToUniqueString("$rsp"), names[7]); |
|
1352 + EXPECT_EQ(ToUniqueString("$rip"), names[16]); |
|
1353 } |
|
1354 diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc |
|
1355 --- a/src/common/linux/dump_symbols.cc |
|
1356 +++ b/src/common/linux/dump_symbols.cc |
|
1357 @@ -81,16 +81,17 @@ |
|
1358 using google_breakpad::ElfClass64; |
|
1359 using google_breakpad::FindElfSectionByName; |
|
1360 using google_breakpad::GetOffset; |
|
1361 using google_breakpad::IsValidElf; |
|
1362 using google_breakpad::Module; |
|
1363 #ifndef NO_STABS_SUPPORT |
|
1364 using google_breakpad::StabsToModule; |
|
1365 #endif |
|
1366 +using google_breakpad::UniqueString; |
|
1367 using google_breakpad::scoped_ptr; |
|
1368 |
|
1369 // |
|
1370 // FDWrapper |
|
1371 // |
|
1372 // Wrapper class to make sure opened file is closed. |
|
1373 // |
|
1374 class FDWrapper { |
|
1375 @@ -278,17 +279,17 @@ |
|
1376 |
|
1377 // Fill REGISTER_NAMES with the register names appropriate to the |
|
1378 // machine architecture given in HEADER, indexed by the register |
|
1379 // numbers used in DWARF call frame information. Return true on |
|
1380 // success, or false if HEADER's machine architecture is not |
|
1381 // supported. |
|
1382 template<typename ElfClass> |
|
1383 bool DwarfCFIRegisterNames(const typename ElfClass::Ehdr* elf_header, |
|
1384 - std::vector<string>* register_names) { |
|
1385 + std::vector<const UniqueString*>* register_names) { |
|
1386 switch (elf_header->e_machine) { |
|
1387 case EM_386: |
|
1388 *register_names = DwarfCFIToModule::RegisterNames::I386(); |
|
1389 return true; |
|
1390 case EM_ARM: |
|
1391 *register_names = DwarfCFIToModule::RegisterNames::ARM(); |
|
1392 return true; |
|
1393 case EM_X86_64: |
|
1394 @@ -306,17 +307,17 @@ |
|
1395 const typename ElfClass::Shdr* section, |
|
1396 const bool eh_frame, |
|
1397 const typename ElfClass::Shdr* got_section, |
|
1398 const typename ElfClass::Shdr* text_section, |
|
1399 const bool big_endian, |
|
1400 Module* module) { |
|
1401 // Find the appropriate set of register names for this file's |
|
1402 // architecture. |
|
1403 - std::vector<string> register_names; |
|
1404 + std::vector<const UniqueString*> register_names; |
|
1405 if (!DwarfCFIRegisterNames<ElfClass>(elf_header, ®ister_names)) { |
|
1406 fprintf(stderr, "%s: unrecognized ELF machine architecture '%d';" |
|
1407 " cannot convert DWARF call frame information\n", |
|
1408 dwarf_filename.c_str(), elf_header->e_machine); |
|
1409 return false; |
|
1410 } |
|
1411 |
|
1412 const dwarf2reader::Endianness endianness = big_endian ? |
|
1413 diff --git a/src/common/mac/dump_syms.mm b/src/common/mac/dump_syms.mm |
|
1414 --- a/src/common/mac/dump_syms.mm |
|
1415 +++ b/src/common/mac/dump_syms.mm |
|
1416 @@ -313,17 +313,17 @@ |
|
1417 } |
|
1418 |
|
1419 bool DumpSymbols::ReadCFI(google_breakpad::Module *module, |
|
1420 const mach_o::Reader &macho_reader, |
|
1421 const mach_o::Section §ion, |
|
1422 bool eh_frame) const { |
|
1423 // Find the appropriate set of register names for this file's |
|
1424 // architecture. |
|
1425 - vector<string> register_names; |
|
1426 + vector<const UniqueString*> register_names; |
|
1427 switch (macho_reader.cpu_type()) { |
|
1428 case CPU_TYPE_X86: |
|
1429 register_names = DwarfCFIToModule::RegisterNames::I386(); |
|
1430 break; |
|
1431 case CPU_TYPE_X86_64: |
|
1432 register_names = DwarfCFIToModule::RegisterNames::X86_64(); |
|
1433 break; |
|
1434 case CPU_TYPE_ARM: |
|
1435 diff --git a/src/common/module.cc b/src/common/module.cc |
|
1436 --- a/src/common/module.cc |
|
1437 +++ b/src/common/module.cc |
|
1438 @@ -33,16 +33,17 @@ |
|
1439 |
|
1440 #include "common/module.h" |
|
1441 |
|
1442 #include <assert.h> |
|
1443 #include <errno.h> |
|
1444 #include <stdio.h> |
|
1445 #include <string.h> |
|
1446 |
|
1447 +#include <algorithm> |
|
1448 #include <iostream> |
|
1449 #include <utility> |
|
1450 |
|
1451 namespace google_breakpad { |
|
1452 |
|
1453 using std::dec; |
|
1454 using std::endl; |
|
1455 using std::hex; |
|
1456 @@ -255,36 +256,50 @@ |
|
1457 strerror(errno)); |
|
1458 return false; |
|
1459 } |
|
1460 |
|
1461 std::ostream& operator<<(std::ostream& stream, const Module::Expr& expr) { |
|
1462 assert(!expr.invalid()); |
|
1463 switch (expr.how_) { |
|
1464 case Module::kExprSimple: |
|
1465 - stream << expr.ident_ << " " << expr.offset_ << " +"; |
|
1466 + stream << FromUniqueString(expr.ident_) << " " << expr.offset_ << " +"; |
|
1467 break; |
|
1468 case Module::kExprSimpleMem: |
|
1469 - stream << expr.ident_ << " " << expr.offset_ << " + ^"; |
|
1470 + stream << FromUniqueString(expr.ident_) << " " << expr.offset_ << " + ^"; |
|
1471 break; |
|
1472 case Module::kExprPostfix: |
|
1473 stream << expr.postfix_; break; |
|
1474 case Module::kExprInvalid: |
|
1475 default: |
|
1476 break; |
|
1477 } |
|
1478 return stream; |
|
1479 } |
|
1480 |
|
1481 bool Module::WriteRuleMap(const RuleMap &rule_map, std::ostream &stream) { |
|
1482 + // Visit the register rules in alphabetical order. Because |
|
1483 + // rule_map has the elements in some arbitrary order, |
|
1484 + // get the names out into a vector, sort them, and visit in |
|
1485 + // sorted order. |
|
1486 + std::vector<const UniqueString*> rr_names; |
|
1487 for (RuleMap::const_iterator it = rule_map.begin(); |
|
1488 it != rule_map.end(); ++it) { |
|
1489 - if (it != rule_map.begin()) |
|
1490 - stream << ' '; |
|
1491 - stream << it->first << ": " << it->second; |
|
1492 + rr_names.push_back(it->first); |
|
1493 + } |
|
1494 + |
|
1495 + std::sort(rr_names.begin(), rr_names.end(), LessThan_UniqueString); |
|
1496 + |
|
1497 + // Now visit the register rules in alphabetical order. |
|
1498 + for (std::vector<const UniqueString*>::const_iterator name = rr_names.begin(); |
|
1499 + name != rr_names.end(); |
|
1500 + ++name) { |
|
1501 + if (name != rr_names.begin()) |
|
1502 + stream << " "; |
|
1503 + stream << FromUniqueString(*name) << ": " << rule_map.find(*name)->second; |
|
1504 } |
|
1505 return stream.good(); |
|
1506 } |
|
1507 |
|
1508 bool Module::Write(std::ostream &stream, SymbolData symbol_data) { |
|
1509 stream << "MODULE " << os_ << " " << architecture_ << " " |
|
1510 << id_ << " " << name_ << endl; |
|
1511 if (!stream.good()) |
|
1512 diff --git a/src/common/module.h b/src/common/module.h |
|
1513 --- a/src/common/module.h |
|
1514 +++ b/src/common/module.h |
|
1515 @@ -41,16 +41,17 @@ |
|
1516 #include <iostream> |
|
1517 #include <map> |
|
1518 #include <set> |
|
1519 #include <string> |
|
1520 #include <vector> |
|
1521 |
|
1522 #include "common/symbol_data.h" |
|
1523 #include "common/using_std_string.h" |
|
1524 +#include "common/unique_string.h" |
|
1525 #include "google_breakpad/common/breakpad_types.h" |
|
1526 |
|
1527 namespace google_breakpad { |
|
1528 |
|
1529 using std::set; |
|
1530 using std::vector; |
|
1531 using std::map; |
|
1532 |
|
1533 @@ -131,69 +132,69 @@ |
|
1534 enum ExprHow { |
|
1535 kExprInvalid = 1, |
|
1536 kExprPostfix, |
|
1537 kExprSimple, |
|
1538 kExprSimpleMem |
|
1539 }; |
|
1540 struct Expr { |
|
1541 // Construct a simple-form expression |
|
1542 - Expr(string ident, long offset, bool deref) { |
|
1543 - if (ident.empty()) { |
|
1544 + Expr(const UniqueString* ident, long offset, bool deref) { |
|
1545 + if (ident == ustr__empty()) { |
|
1546 Expr(); |
|
1547 } else { |
|
1548 postfix_ = ""; |
|
1549 ident_ = ident; |
|
1550 offset_ = offset; |
|
1551 how_ = deref ? kExprSimpleMem : kExprSimple; |
|
1552 } |
|
1553 } |
|
1554 // Construct an expression from a postfix string |
|
1555 Expr(string postfix) { |
|
1556 if (postfix.empty()) { |
|
1557 Expr(); |
|
1558 } else { |
|
1559 postfix_ = postfix; |
|
1560 - ident_ = ""; |
|
1561 + ident_ = NULL; |
|
1562 offset_ = 0; |
|
1563 how_ = kExprPostfix; |
|
1564 } |
|
1565 } |
|
1566 // Construct an invalid expression |
|
1567 Expr() { |
|
1568 postfix_ = ""; |
|
1569 - ident_ = ""; |
|
1570 + ident_ = NULL; |
|
1571 offset_ = 0; |
|
1572 how_ = kExprInvalid; |
|
1573 } |
|
1574 bool invalid() const { return how_ == kExprInvalid; } |
|
1575 bool operator==(const Expr& other) const { |
|
1576 return how_ == other.how_ && |
|
1577 ident_ == other.ident_ && |
|
1578 offset_ == other.offset_ && |
|
1579 postfix_ == other.postfix_; |
|
1580 } |
|
1581 |
|
1582 // The identifier that gives the starting value for simple expressions. |
|
1583 - string ident_; |
|
1584 + const UniqueString* ident_; |
|
1585 // The offset to add for simple expressions. |
|
1586 long offset_; |
|
1587 // The Postfix expression string to evaluate for non-simple expressions. |
|
1588 string postfix_; |
|
1589 // The operation expressed by this expression. |
|
1590 ExprHow how_; |
|
1591 |
|
1592 friend std::ostream& operator<<(std::ostream& stream, const Expr& expr); |
|
1593 }; |
|
1594 |
|
1595 // A map from register names to expressions that recover |
|
1596 // their values. This can represent a complete set of rules to |
|
1597 // follow at some address, or a set of changes to be applied to an |
|
1598 // extant set of rules. |
|
1599 - typedef map<string, Expr> RuleMap; |
|
1600 + typedef map<const UniqueString*, Expr> RuleMap; |
|
1601 |
|
1602 // A map from addresses to RuleMaps, representing changes that take |
|
1603 // effect at given addresses. |
|
1604 typedef map<Address, RuleMap> RuleChangeMap; |
|
1605 |
|
1606 // A range of 'STACK CFI' stack walking information. An instance of |
|
1607 // this structure corresponds to a 'STACK CFI INIT' record and the |
|
1608 // subsequent 'STACK CFI' records that fall within its range. |
|
1609 diff --git a/src/common/module_unittest.cc b/src/common/module_unittest.cc |
|
1610 --- a/src/common/module_unittest.cc |
|
1611 +++ b/src/common/module_unittest.cc |
|
1612 @@ -40,16 +40,18 @@ |
|
1613 #include <sstream> |
|
1614 #include <string> |
|
1615 |
|
1616 #include "breakpad_googletest_includes.h" |
|
1617 #include "common/module.h" |
|
1618 #include "common/using_std_string.h" |
|
1619 |
|
1620 using google_breakpad::Module; |
|
1621 +using google_breakpad::ToUniqueString; |
|
1622 +using google_breakpad::ustr__ZDcfa; |
|
1623 using std::stringstream; |
|
1624 using std::vector; |
|
1625 using testing::ContainerEq; |
|
1626 |
|
1627 static Module::Function *generate_duplicate_function(const string &name) { |
|
1628 const Module::Address DUP_ADDRESS = 0xd35402aac7a7ad5cLL; |
|
1629 const Module::Address DUP_SIZE = 0x200b26e605f99071LL; |
|
1630 const Module::Address DUP_PARAMETER_SIZE = 0xf14ac4fed48c4a99LL; |
|
1631 @@ -125,21 +127,27 @@ |
|
1632 function->lines.push_back(line1); |
|
1633 |
|
1634 m.AddFunction(function); |
|
1635 |
|
1636 // Some stack information. |
|
1637 Module::StackFrameEntry *entry = new Module::StackFrameEntry(); |
|
1638 entry->address = 0x30f9e5c83323973dULL; |
|
1639 entry->size = 0x49fc9ca7c7c13dc2ULL; |
|
1640 - entry->initial_rules[".cfa"] = Module::Expr("he was a handsome man"); |
|
1641 - entry->initial_rules["and"] = Module::Expr("what i want to know is"); |
|
1642 - entry->rule_changes[0x30f9e5c83323973eULL]["how"] = |
|
1643 - Module::Expr("do you like your blueeyed boy"); |
|
1644 - entry->rule_changes[0x30f9e5c83323973eULL]["Mister"] = Module::Expr("Death"); |
|
1645 + entry->initial_rules[ustr__ZDcfa()] = Module::Expr("he was a handsome man"); |
|
1646 + entry->initial_rules[ToUniqueString("and")] = |
|
1647 + Module::Expr("what i want to know is"); |
|
1648 + entry->initial_rules[ToUniqueString("stallion")] = |
|
1649 + Module::Expr(ToUniqueString("and break"), 8, false); |
|
1650 + entry->initial_rules[ToUniqueString("onetwothreefourfive")] = |
|
1651 + Module::Expr(ToUniqueString("pigeonsjustlikethat"), 42, true); |
|
1652 + entry->rule_changes[0x30f9e5c83323973eULL][ToUniqueString("how")] = |
|
1653 + Module::Expr("do you like your blueeyed boy"); |
|
1654 + entry->rule_changes[0x30f9e5c83323973eULL][ToUniqueString("Mister")] = |
|
1655 + Module::Expr("Death"); |
|
1656 m.AddStackFrameEntry(entry); |
|
1657 |
|
1658 // Set the load address. Doing this after adding all the data to |
|
1659 // the module must work fine. |
|
1660 m.SetLoadAddress(0x2ab698b0b6407073LL); |
|
1661 |
|
1662 m.Write(s, ALL_SYMBOL_DATA); |
|
1663 string contents = s.str(); |
|
1664 @@ -147,17 +155,19 @@ |
|
1665 "FILE 0 filename-a.cc\n" |
|
1666 "FILE 1 filename-b.cc\n" |
|
1667 "FUNC 9410dc39a798c580 2922088f98d3f6fc e5e9aa008bd5f0d0" |
|
1668 " A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)\n" |
|
1669 "b03cc3106d47eb91 cf621b8d324d0eb 67519080 0\n" |
|
1670 "9410dc39a798c580 1c2be6d6c5af2611 41676901 1\n" |
|
1671 "STACK CFI INIT 6434d177ce326ca 49fc9ca7c7c13dc2" |
|
1672 " .cfa: he was a handsome man" |
|
1673 - " and: what i want to know is\n" |
|
1674 + " and: what i want to know is" |
|
1675 + " onetwothreefourfive: pigeonsjustlikethat 42 + ^" |
|
1676 + " stallion: and break 8 +\n" |
|
1677 "STACK CFI 6434d177ce326cb" |
|
1678 " Mister: Death" |
|
1679 " how: do you like your blueeyed boy\n", |
|
1680 contents.c_str()); |
|
1681 } |
|
1682 |
|
1683 TEST(Write, OmitUnusedFiles) { |
|
1684 Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); |
|
1685 @@ -229,21 +239,23 @@ |
|
1686 function->lines.push_back(line1); |
|
1687 |
|
1688 m.AddFunction(function); |
|
1689 |
|
1690 // Some stack information. |
|
1691 Module::StackFrameEntry *entry = new Module::StackFrameEntry(); |
|
1692 entry->address = 0x30f9e5c83323973dULL; |
|
1693 entry->size = 0x49fc9ca7c7c13dc2ULL; |
|
1694 - entry->initial_rules[".cfa"] = Module::Expr("he was a handsome man"); |
|
1695 - entry->initial_rules["and"] = Module::Expr("what i want to know is"); |
|
1696 - entry->rule_changes[0x30f9e5c83323973eULL]["how"] = |
|
1697 - Module::Expr("do you like your blueeyed boy"); |
|
1698 - entry->rule_changes[0x30f9e5c83323973eULL]["Mister"] = Module::Expr("Death"); |
|
1699 + entry->initial_rules[ustr__ZDcfa()] = Module::Expr("he was a handsome man"); |
|
1700 + entry->initial_rules[ToUniqueString("and")] = |
|
1701 + Module::Expr("what i want to know is"); |
|
1702 + entry->rule_changes[0x30f9e5c83323973eULL][ToUniqueString("how")] = |
|
1703 + Module::Expr("do you like your blueeyed boy"); |
|
1704 + entry->rule_changes[0x30f9e5c83323973eULL][ToUniqueString("Mister")] = |
|
1705 + Module::Expr("Death"); |
|
1706 m.AddStackFrameEntry(entry); |
|
1707 |
|
1708 // Set the load address. Doing this after adding all the data to |
|
1709 // the module must work fine. |
|
1710 m.SetLoadAddress(0x2ab698b0b6407073LL); |
|
1711 |
|
1712 m.Write(s, NO_CFI); |
|
1713 string contents = s.str(); |
|
1714 @@ -305,33 +317,36 @@ |
|
1715 entry1->address = 0xddb5f41285aa7757ULL; |
|
1716 entry1->size = 0x1486493370dc5073ULL; |
|
1717 m.AddStackFrameEntry(entry1); |
|
1718 |
|
1719 // Second STACK CFI entry, with initial rules but no deltas. |
|
1720 Module::StackFrameEntry *entry2 = new Module::StackFrameEntry(); |
|
1721 entry2->address = 0x8064f3af5e067e38ULL; |
|
1722 entry2->size = 0x0de2a5ee55509407ULL; |
|
1723 - entry2->initial_rules[".cfa"] = Module::Expr("I think that I shall never see"); |
|
1724 - entry2->initial_rules["stromboli"] = Module::Expr("a poem lovely as a tree"); |
|
1725 - entry2->initial_rules["cannoli"] = Module::Expr("a tree whose hungry mouth is prest"); |
|
1726 + entry2->initial_rules[ustr__ZDcfa()] = |
|
1727 + Module::Expr("I think that I shall never see"); |
|
1728 + entry2->initial_rules[ToUniqueString("stromboli")] = |
|
1729 + Module::Expr("a poem lovely as a tree"); |
|
1730 + entry2->initial_rules[ToUniqueString("cannoli")] = |
|
1731 + Module::Expr("a tree whose hungry mouth is prest"); |
|
1732 m.AddStackFrameEntry(entry2); |
|
1733 |
|
1734 // Third STACK CFI entry, with initial rules and deltas. |
|
1735 Module::StackFrameEntry *entry3 = new Module::StackFrameEntry(); |
|
1736 entry3->address = 0x5e8d0db0a7075c6cULL; |
|
1737 entry3->size = 0x1c7edb12a7aea229ULL; |
|
1738 - entry3->initial_rules[".cfa"] = Module::Expr("Whose woods are these"); |
|
1739 - entry3->rule_changes[0x47ceb0f63c269d7fULL]["calzone"] = |
|
1740 + entry3->initial_rules[ustr__ZDcfa()] = Module::Expr("Whose woods are these"); |
|
1741 + entry3->rule_changes[0x47ceb0f63c269d7fULL][ToUniqueString("calzone")] = |
|
1742 Module::Expr("the village though"); |
|
1743 - entry3->rule_changes[0x47ceb0f63c269d7fULL]["cannoli"] = |
|
1744 + entry3->rule_changes[0x47ceb0f63c269d7fULL][ToUniqueString("cannoli")] = |
|
1745 Module::Expr("he will not see me stopping here"); |
|
1746 - entry3->rule_changes[0x36682fad3763ffffULL]["stromboli"] = |
|
1747 + entry3->rule_changes[0x36682fad3763ffffULL][ToUniqueString("stromboli")] = |
|
1748 Module::Expr("his house is in"); |
|
1749 - entry3->rule_changes[0x36682fad3763ffffULL][".cfa"] = |
|
1750 + entry3->rule_changes[0x36682fad3763ffffULL][ustr__ZDcfa()] = |
|
1751 Module::Expr("I think I know"); |
|
1752 m.AddStackFrameEntry(entry3); |
|
1753 |
|
1754 // Check that Write writes STACK CFI records properly. |
|
1755 m.Write(s, ALL_SYMBOL_DATA); |
|
1756 string contents = s.str(); |
|
1757 EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" |
|
1758 "STACK CFI INIT 5e8d0db0a7075c6c 1c7edb12a7aea229" |
|
1759 @@ -352,33 +367,39 @@ |
|
1760 // Check that GetStackFrameEntries works. |
|
1761 vector<Module::StackFrameEntry *> entries; |
|
1762 m.GetStackFrameEntries(&entries); |
|
1763 ASSERT_EQ(3U, entries.size()); |
|
1764 // Check first entry. |
|
1765 EXPECT_EQ(0x5e8d0db0a7075c6cULL, entries[0]->address); |
|
1766 EXPECT_EQ(0x1c7edb12a7aea229ULL, entries[0]->size); |
|
1767 Module::RuleMap entry1_initial; |
|
1768 - entry1_initial[".cfa"] = Module::Expr("Whose woods are these"); |
|
1769 + entry1_initial[ustr__ZDcfa()] = Module::Expr("Whose woods are these"); |
|
1770 EXPECT_THAT(entries[0]->initial_rules, ContainerEq(entry1_initial)); |
|
1771 Module::RuleChangeMap entry1_changes; |
|
1772 - entry1_changes[0x36682fad3763ffffULL][".cfa"] = Module::Expr("I think I know"); |
|
1773 - entry1_changes[0x36682fad3763ffffULL]["stromboli"] = Module::Expr("his house is in"); |
|
1774 - entry1_changes[0x47ceb0f63c269d7fULL]["calzone"] = Module::Expr("the village though"); |
|
1775 - entry1_changes[0x47ceb0f63c269d7fULL]["cannoli"] = |
|
1776 - Module::Expr("he will not see me stopping here"); |
|
1777 + entry1_changes[0x36682fad3763ffffULL][ustr__ZDcfa()] = |
|
1778 + Module::Expr("I think I know"); |
|
1779 + entry1_changes[0x36682fad3763ffffULL][ToUniqueString("stromboli")] = |
|
1780 + Module::Expr("his house is in"); |
|
1781 + entry1_changes[0x47ceb0f63c269d7fULL][ToUniqueString("calzone")] = |
|
1782 + Module::Expr("the village though"); |
|
1783 + entry1_changes[0x47ceb0f63c269d7fULL][ToUniqueString("cannoli")] = |
|
1784 + Module::Expr("he will not see me stopping here"); |
|
1785 EXPECT_THAT(entries[0]->rule_changes, ContainerEq(entry1_changes)); |
|
1786 // Check second entry. |
|
1787 EXPECT_EQ(0x8064f3af5e067e38ULL, entries[1]->address); |
|
1788 EXPECT_EQ(0x0de2a5ee55509407ULL, entries[1]->size); |
|
1789 ASSERT_EQ(3U, entries[1]->initial_rules.size()); |
|
1790 Module::RuleMap entry2_initial; |
|
1791 - entry2_initial[".cfa"] = Module::Expr("I think that I shall never see"); |
|
1792 - entry2_initial["stromboli"] = Module::Expr("a poem lovely as a tree"); |
|
1793 - entry2_initial["cannoli"] = Module::Expr("a tree whose hungry mouth is prest"); |
|
1794 + entry2_initial[ustr__ZDcfa()] = |
|
1795 + Module::Expr("I think that I shall never see"); |
|
1796 + entry2_initial[ToUniqueString("stromboli")] = |
|
1797 + Module::Expr("a poem lovely as a tree"); |
|
1798 + entry2_initial[ToUniqueString("cannoli")] = |
|
1799 + Module::Expr("a tree whose hungry mouth is prest"); |
|
1800 EXPECT_THAT(entries[1]->initial_rules, ContainerEq(entry2_initial)); |
|
1801 ASSERT_EQ(0U, entries[1]->rule_changes.size()); |
|
1802 // Check third entry. |
|
1803 EXPECT_EQ(0xddb5f41285aa7757ULL, entries[2]->address); |
|
1804 EXPECT_EQ(0x1486493370dc5073ULL, entries[2]->size); |
|
1805 ASSERT_EQ(0U, entries[2]->initial_rules.size()); |
|
1806 ASSERT_EQ(0U, entries[2]->rule_changes.size()); |
|
1807 } |
|
1808 @@ -585,33 +606,36 @@ |
|
1809 entry1->address = 0x2000; |
|
1810 entry1->size = 0x900; |
|
1811 m.AddStackFrameEntry(entry1); |
|
1812 |
|
1813 // Second STACK CFI entry, with initial rules but no deltas. |
|
1814 Module::StackFrameEntry *entry2 = new Module::StackFrameEntry(); |
|
1815 entry2->address = 0x3000; |
|
1816 entry2->size = 0x900; |
|
1817 - entry2->initial_rules[".cfa"] = Module::Expr("I think that I shall never see"); |
|
1818 - entry2->initial_rules["stromboli"] = Module::Expr("a poem lovely as a tree"); |
|
1819 - entry2->initial_rules["cannoli"] = Module::Expr("a tree whose hungry mouth is prest"); |
|
1820 + entry2->initial_rules[ustr__ZDcfa()] = |
|
1821 + Module::Expr("I think that I shall never see"); |
|
1822 + entry2->initial_rules[ToUniqueString("stromboli")] = |
|
1823 + Module::Expr("a poem lovely as a tree"); |
|
1824 + entry2->initial_rules[ToUniqueString("cannoli")] = |
|
1825 + Module::Expr("a tree whose hungry mouth is prest"); |
|
1826 m.AddStackFrameEntry(entry2); |
|
1827 |
|
1828 // Third STACK CFI entry, with initial rules and deltas. |
|
1829 Module::StackFrameEntry *entry3 = new Module::StackFrameEntry(); |
|
1830 entry3->address = 0x1000; |
|
1831 entry3->size = 0x900; |
|
1832 - entry3->initial_rules[".cfa"] = Module::Expr("Whose woods are these"); |
|
1833 - entry3->rule_changes[0x47ceb0f63c269d7fULL]["calzone"] = |
|
1834 + entry3->initial_rules[ustr__ZDcfa()] = Module::Expr("Whose woods are these"); |
|
1835 + entry3->rule_changes[0x47ceb0f63c269d7fULL][ToUniqueString("calzone")] = |
|
1836 Module::Expr("the village though"); |
|
1837 - entry3->rule_changes[0x47ceb0f63c269d7fULL]["cannoli"] = |
|
1838 + entry3->rule_changes[0x47ceb0f63c269d7fULL][ToUniqueString("cannoli")] = |
|
1839 Module::Expr("he will not see me stopping here"); |
|
1840 - entry3->rule_changes[0x36682fad3763ffffULL]["stromboli"] = |
|
1841 + entry3->rule_changes[0x36682fad3763ffffULL][ToUniqueString("stromboli")] = |
|
1842 Module::Expr("his house is in"); |
|
1843 - entry3->rule_changes[0x36682fad3763ffffULL][".cfa"] = |
|
1844 + entry3->rule_changes[0x36682fad3763ffffULL][ustr__ZDcfa()] = |
|
1845 Module::Expr("I think I know"); |
|
1846 m.AddStackFrameEntry(entry3); |
|
1847 |
|
1848 Module::StackFrameEntry* s = m.FindStackFrameEntryByAddress(0x1000); |
|
1849 EXPECT_EQ(entry3, s); |
|
1850 s = m.FindStackFrameEntryByAddress(0x18FF); |
|
1851 EXPECT_EQ(entry3, s); |
|
1852 |
|
1853 diff --git a/src/common/unique_string.cc b/src/common/unique_string.cc |
|
1854 new file mode 100644 |
|
1855 --- /dev/null |
|
1856 +++ b/src/common/unique_string.cc |
|
1857 @@ -0,0 +1,110 @@ |
|
1858 +// Copyright (c) 2013 Google Inc. |
|
1859 +// All rights reserved. |
|
1860 +// |
|
1861 +// Redistribution and use in source and binary forms, with or without |
|
1862 +// modification, are permitted provided that the following conditions are |
|
1863 +// met: |
|
1864 +// |
|
1865 +// * Redistributions of source code must retain the above copyright |
|
1866 +// notice, this list of conditions and the following disclaimer. |
|
1867 +// * Redistributions in binary form must reproduce the above |
|
1868 +// copyright notice, this list of conditions and the following disclaimer |
|
1869 +// in the documentation and/or other materials provided with the |
|
1870 +// distribution. |
|
1871 +// * Neither the name of Google Inc. nor the names of its |
|
1872 +// contributors may be used to endorse or promote products derived from |
|
1873 +// this software without specific prior written permission. |
|
1874 +// |
|
1875 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
1876 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
1877 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
1878 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
1879 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
1880 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
1881 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
1882 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
1883 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
1884 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
1885 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
1886 + |
|
1887 +#include <string> |
|
1888 +#include <map> |
|
1889 + |
|
1890 +#include <stdlib.h> |
|
1891 +#include <string.h> |
|
1892 + |
|
1893 +#include "common/unique_string.h" |
|
1894 + |
|
1895 +namespace google_breakpad { |
|
1896 + |
|
1897 +/////////////////////////////////////////////////////////////////// |
|
1898 +// UniqueString |
|
1899 +// |
|
1900 +class UniqueString { |
|
1901 + public: |
|
1902 + UniqueString(string str) { str_ = strdup(str.c_str()); } |
|
1903 + ~UniqueString() { free(reinterpret_cast<void*>(const_cast<char*>(str_))); } |
|
1904 + const char* str_; |
|
1905 +}; |
|
1906 + |
|
1907 +class UniqueStringUniverse { |
|
1908 + public: |
|
1909 + UniqueStringUniverse() {}; |
|
1910 + const UniqueString* FindOrCopy(string str) { |
|
1911 + std::map<string, UniqueString*>::iterator it = map_.find(str); |
|
1912 + if (it == map_.end()) { |
|
1913 + UniqueString* ustr = new UniqueString(str); |
|
1914 + map_[str] = ustr; |
|
1915 + return ustr; |
|
1916 + } else { |
|
1917 + return it->second; |
|
1918 + } |
|
1919 + } |
|
1920 + private: |
|
1921 + std::map<string, UniqueString*> map_; |
|
1922 +}; |
|
1923 + |
|
1924 +// |
|
1925 +/////////////////////////////////////////////////////////////////// |
|
1926 + |
|
1927 + |
|
1928 +static UniqueStringUniverse* sUSU = NULL; |
|
1929 + |
|
1930 + |
|
1931 +// This isn't threadsafe. |
|
1932 +const UniqueString* ToUniqueString(string str) { |
|
1933 + if (!sUSU) { |
|
1934 + sUSU = new UniqueStringUniverse(); |
|
1935 + } |
|
1936 + return sUSU->FindOrCopy(str); |
|
1937 +} |
|
1938 + |
|
1939 +// This isn't threadsafe. |
|
1940 +const UniqueString* ToUniqueString_n(const char* str, size_t n) { |
|
1941 + if (!sUSU) { |
|
1942 + sUSU = new UniqueStringUniverse(); |
|
1943 + } |
|
1944 + string key(str, n); |
|
1945 + return sUSU->FindOrCopy(key); |
|
1946 +} |
|
1947 + |
|
1948 +const char Index(const UniqueString* us, int ix) |
|
1949 +{ |
|
1950 + return us->str_[ix]; |
|
1951 +} |
|
1952 + |
|
1953 +const char* const FromUniqueString(const UniqueString* ustr) |
|
1954 +{ |
|
1955 + return ustr->str_; |
|
1956 +} |
|
1957 + |
|
1958 +int StrcmpUniqueString(const UniqueString* us1, const UniqueString* us2) { |
|
1959 + return strcmp(us1->str_, us2->str_); |
|
1960 +} |
|
1961 + |
|
1962 +bool LessThan_UniqueString(const UniqueString* us1, const UniqueString* us2) { |
|
1963 + int r = StrcmpUniqueString(us1, us2); |
|
1964 + return r < 0; |
|
1965 +} |
|
1966 + |
|
1967 +} // namespace google_breakpad |
|
1968 diff --git a/src/common/unique_string.h b/src/common/unique_string.h |
|
1969 new file mode 100644 |
|
1970 --- /dev/null |
|
1971 +++ b/src/common/unique_string.h |
|
1972 @@ -0,0 +1,239 @@ |
|
1973 +// Copyright (c) 2013 Google Inc. |
|
1974 +// All rights reserved. |
|
1975 +// |
|
1976 +// Redistribution and use in source and binary forms, with or without |
|
1977 +// modification, are permitted provided that the following conditions are |
|
1978 +// met: |
|
1979 +// |
|
1980 +// * Redistributions of source code must retain the above copyright |
|
1981 +// notice, this list of conditions and the following disclaimer. |
|
1982 +// * Redistributions in binary form must reproduce the above |
|
1983 +// copyright notice, this list of conditions and the following disclaimer |
|
1984 +// in the documentation and/or other materials provided with the |
|
1985 +// distribution. |
|
1986 +// * Neither the name of Google Inc. nor the names of its |
|
1987 +// contributors may be used to endorse or promote products derived from |
|
1988 +// this software without specific prior written permission. |
|
1989 +// |
|
1990 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
1991 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
1992 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
1993 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
1994 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
1995 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
1996 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
1997 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
1998 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
1999 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
2000 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
2001 + |
|
2002 +#ifndef COMMON_UNIQUE_STRING_H_ |
|
2003 +#define COMMON_UNIQUE_STRING_H_ |
|
2004 + |
|
2005 +#include <string> |
|
2006 +#include "common/using_std_string.h" |
|
2007 + |
|
2008 +namespace google_breakpad { |
|
2009 + |
|
2010 +// Abstract type |
|
2011 +class UniqueString; |
|
2012 + |
|
2013 +// Unique-ify a string. |ToUniqueString| can never return NULL. |
|
2014 +const UniqueString* ToUniqueString(string); |
|
2015 + |
|
2016 +// ditto, starting instead from the first n characters of a C string |
|
2017 +const UniqueString* ToUniqueString_n(const char* str, size_t n); |
|
2018 + |
|
2019 +// Pull chars out of the string. No range checking. |
|
2020 +const char Index(const UniqueString*, int); |
|
2021 + |
|
2022 +// Get the contained C string (debugging only) |
|
2023 +const char* const FromUniqueString(const UniqueString*); |
|
2024 + |
|
2025 +// Do a strcmp-style comparison on the contained C string |
|
2026 +int StrcmpUniqueString(const UniqueString*, const UniqueString*); |
|
2027 + |
|
2028 +// Less-than comparison of two UniqueStrings, usable for std::sort. |
|
2029 +bool LessThan_UniqueString(const UniqueString*, const UniqueString*); |
|
2030 + |
|
2031 +// Some handy pre-uniqified strings. Z is an escape character: |
|
2032 +// ZS '$' |
|
2033 +// ZD '.' |
|
2034 +// Zeq '=' |
|
2035 +// Zplus '+' |
|
2036 +// Zstar '*' |
|
2037 +// Zslash '/' |
|
2038 +// Zpercent '%' |
|
2039 +// Zat '@' |
|
2040 +// Zcaret '^' |
|
2041 + |
|
2042 +// Note that ustr__empty and (UniqueString*)NULL are considered |
|
2043 +// to be different. |
|
2044 +// |
|
2045 +// Unfortunately these have to be written as functions so as to |
|
2046 +// make them safe to use in static initialisers. |
|
2047 + |
|
2048 +// "" |
|
2049 +inline static const UniqueString* ustr__empty() { |
|
2050 + static const UniqueString* us = NULL; |
|
2051 + if (!us) us = ToUniqueString(""); |
|
2052 + return us; |
|
2053 +} |
|
2054 + |
|
2055 +// "$eip" |
|
2056 +inline static const UniqueString* ustr__ZSeip() { |
|
2057 + static const UniqueString* us = NULL; |
|
2058 + if (!us) us = ToUniqueString("$eip"); |
|
2059 + return us; |
|
2060 +} |
|
2061 + |
|
2062 +// "$ebp" |
|
2063 +inline static const UniqueString* ustr__ZSebp() { |
|
2064 + static const UniqueString* us = NULL; |
|
2065 + if (!us) us = ToUniqueString("$ebp"); |
|
2066 + return us; |
|
2067 +} |
|
2068 + |
|
2069 +// "$esp" |
|
2070 +inline static const UniqueString* ustr__ZSesp() { |
|
2071 + static const UniqueString* us = NULL; |
|
2072 + if (!us) us = ToUniqueString("$esp"); |
|
2073 + return us; |
|
2074 +} |
|
2075 + |
|
2076 +// "$ebx" |
|
2077 +inline static const UniqueString* ustr__ZSebx() { |
|
2078 + static const UniqueString* us = NULL; |
|
2079 + if (!us) us = ToUniqueString("$ebx"); |
|
2080 + return us; |
|
2081 +} |
|
2082 + |
|
2083 +// "$esi" |
|
2084 +inline static const UniqueString* ustr__ZSesi() { |
|
2085 + static const UniqueString* us = NULL; |
|
2086 + if (!us) us = ToUniqueString("$esi"); |
|
2087 + return us; |
|
2088 +} |
|
2089 + |
|
2090 +// "$edi" |
|
2091 +inline static const UniqueString* ustr__ZSedi() { |
|
2092 + static const UniqueString* us = NULL; |
|
2093 + if (!us) us = ToUniqueString("$edi"); |
|
2094 + return us; |
|
2095 +} |
|
2096 + |
|
2097 +// ".cbCalleeParams" |
|
2098 +inline static const UniqueString* ustr__ZDcbCalleeParams() { |
|
2099 + static const UniqueString* us = NULL; |
|
2100 + if (!us) us = ToUniqueString(".cbCalleeParams"); |
|
2101 + return us; |
|
2102 +} |
|
2103 + |
|
2104 +// ".cbSavedRegs" |
|
2105 +inline static const UniqueString* ustr__ZDcbSavedRegs() { |
|
2106 + static const UniqueString* us = NULL; |
|
2107 + if (!us) us = ToUniqueString(".cbSavedRegs"); |
|
2108 + return us; |
|
2109 +} |
|
2110 + |
|
2111 +// ".cbLocals" |
|
2112 +inline static const UniqueString* ustr__ZDcbLocals() { |
|
2113 + static const UniqueString* us = NULL; |
|
2114 + if (!us) us = ToUniqueString(".cbLocals"); |
|
2115 + return us; |
|
2116 +} |
|
2117 + |
|
2118 +// ".raSearchStart" |
|
2119 +inline static const UniqueString* ustr__ZDraSearchStart() { |
|
2120 + static const UniqueString* us = NULL; |
|
2121 + if (!us) us = ToUniqueString(".raSearchStart"); |
|
2122 + return us; |
|
2123 +} |
|
2124 + |
|
2125 +// ".raSearch" |
|
2126 +inline static const UniqueString* ustr__ZDraSearch() { |
|
2127 + static const UniqueString* us = NULL; |
|
2128 + if (!us) us = ToUniqueString(".raSearch"); |
|
2129 + return us; |
|
2130 +} |
|
2131 + |
|
2132 +// ".cbParams" |
|
2133 +inline static const UniqueString* ustr__ZDcbParams() { |
|
2134 + static const UniqueString* us = NULL; |
|
2135 + if (!us) us = ToUniqueString(".cbParams"); |
|
2136 + return us; |
|
2137 +} |
|
2138 + |
|
2139 +// "+" |
|
2140 +inline static const UniqueString* ustr__Zplus() { |
|
2141 + static const UniqueString* us = NULL; |
|
2142 + if (!us) us = ToUniqueString("+"); |
|
2143 + return us; |
|
2144 +} |
|
2145 + |
|
2146 +// "-" |
|
2147 +inline static const UniqueString* ustr__Zminus() { |
|
2148 + static const UniqueString* us = NULL; |
|
2149 + if (!us) us = ToUniqueString("-"); |
|
2150 + return us; |
|
2151 +} |
|
2152 + |
|
2153 +// "*" |
|
2154 +inline static const UniqueString* ustr__Zstar() { |
|
2155 + static const UniqueString* us = NULL; |
|
2156 + if (!us) us = ToUniqueString("*"); |
|
2157 + return us; |
|
2158 +} |
|
2159 + |
|
2160 +// "/" |
|
2161 +inline static const UniqueString* ustr__Zslash() { |
|
2162 + static const UniqueString* us = NULL; |
|
2163 + if (!us) us = ToUniqueString("/"); |
|
2164 + return us; |
|
2165 +} |
|
2166 + |
|
2167 +// "%" |
|
2168 +inline static const UniqueString* ustr__Zpercent() { |
|
2169 + static const UniqueString* us = NULL; |
|
2170 + if (!us) us = ToUniqueString("%"); |
|
2171 + return us; |
|
2172 +} |
|
2173 + |
|
2174 +// "@" |
|
2175 +inline static const UniqueString* ustr__Zat() { |
|
2176 + static const UniqueString* us = NULL; |
|
2177 + if (!us) us = ToUniqueString("@"); |
|
2178 + return us; |
|
2179 +} |
|
2180 + |
|
2181 +// "^" |
|
2182 +inline static const UniqueString* ustr__Zcaret() { |
|
2183 + static const UniqueString* us = NULL; |
|
2184 + if (!us) us = ToUniqueString("^"); |
|
2185 + return us; |
|
2186 +} |
|
2187 + |
|
2188 +// "=" |
|
2189 +inline static const UniqueString* ustr__Zeq() { |
|
2190 + static const UniqueString* us = NULL; |
|
2191 + if (!us) us = ToUniqueString("="); |
|
2192 + return us; |
|
2193 +} |
|
2194 + |
|
2195 +// ".cfa" |
|
2196 +inline static const UniqueString* ustr__ZDcfa() { |
|
2197 + static const UniqueString* us = NULL; |
|
2198 + if (!us) us = ToUniqueString(".cfa"); |
|
2199 + return us; |
|
2200 +} |
|
2201 + |
|
2202 +// ".ra" |
|
2203 +inline static const UniqueString* ustr__ZDra() { |
|
2204 + static const UniqueString* us = NULL; |
|
2205 + if (!us) us = ToUniqueString(".ra"); |
|
2206 + return us; |
|
2207 +} |
|
2208 + |
|
2209 +} // namespace google_breakpad |
|
2210 + |
|
2211 +#endif // COMMON_UNIQUE_STRING_H_ |
|
2212 diff --git a/src/processor/basic_source_line_resolver_unittest.cc b/src/processor/basic_source_line_resolver_unittest.cc |
|
2213 --- a/src/processor/basic_source_line_resolver_unittest.cc |
|
2214 +++ b/src/processor/basic_source_line_resolver_unittest.cc |
|
2215 @@ -43,21 +43,30 @@ |
|
2216 #include "processor/windows_frame_info.h" |
|
2217 #include "processor/cfi_frame_info.h" |
|
2218 |
|
2219 namespace { |
|
2220 |
|
2221 using google_breakpad::BasicSourceLineResolver; |
|
2222 using google_breakpad::CFIFrameInfo; |
|
2223 using google_breakpad::CodeModule; |
|
2224 +using google_breakpad::FromUniqueString; |
|
2225 using google_breakpad::MemoryRegion; |
|
2226 using google_breakpad::StackFrame; |
|
2227 +using google_breakpad::ToUniqueString; |
|
2228 using google_breakpad::WindowsFrameInfo; |
|
2229 using google_breakpad::linked_ptr; |
|
2230 using google_breakpad::scoped_ptr; |
|
2231 +using google_breakpad::ustr__ZDcfa; |
|
2232 +using google_breakpad::ustr__ZDra; |
|
2233 +using google_breakpad::ustr__ZSebx; |
|
2234 +using google_breakpad::ustr__ZSebp; |
|
2235 +using google_breakpad::ustr__ZSedi; |
|
2236 +using google_breakpad::ustr__ZSesi; |
|
2237 +using google_breakpad::ustr__ZSesp; |
|
2238 |
|
2239 class TestCodeModule : public CodeModule { |
|
2240 public: |
|
2241 TestCodeModule(string code_file) : code_file_(code_file) {} |
|
2242 virtual ~TestCodeModule() {} |
|
2243 |
|
2244 virtual uint64_t base_address() const { return 0; } |
|
2245 virtual uint64_t size() const { return 0xb000; } |
|
2246 @@ -107,34 +116,34 @@ |
|
2247 // association. (That is, ACTUAL's associations should be a subset of |
|
2248 // EXPECTED's.) Also verify that ACTUAL has associations for ".ra" and |
|
2249 // ".cfa". |
|
2250 static bool VerifyRegisters( |
|
2251 const char *file, int line, |
|
2252 const CFIFrameInfo::RegisterValueMap<uint32_t> &expected, |
|
2253 const CFIFrameInfo::RegisterValueMap<uint32_t> &actual) { |
|
2254 CFIFrameInfo::RegisterValueMap<uint32_t>::const_iterator a; |
|
2255 - a = actual.find(".cfa"); |
|
2256 + a = actual.find(ustr__ZDcfa()); |
|
2257 if (a == actual.end()) |
|
2258 return false; |
|
2259 - a = actual.find(".ra"); |
|
2260 + a = actual.find(ustr__ZDra()); |
|
2261 if (a == actual.end()) |
|
2262 return false; |
|
2263 for (a = actual.begin(); a != actual.end(); a++) { |
|
2264 CFIFrameInfo::RegisterValueMap<uint32_t>::const_iterator e = |
|
2265 expected.find(a->first); |
|
2266 if (e == expected.end()) { |
|
2267 fprintf(stderr, "%s:%d: unexpected register '%s' recovered, value 0x%x\n", |
|
2268 - file, line, a->first.c_str(), a->second); |
|
2269 + file, line, FromUniqueString(a->first), a->second); |
|
2270 return false; |
|
2271 } |
|
2272 if (e->second != a->second) { |
|
2273 fprintf(stderr, |
|
2274 "%s:%d: register '%s' recovered value was 0x%x, expected 0x%x\n", |
|
2275 - file, line, a->first.c_str(), a->second, e->second); |
|
2276 + file, line, FromUniqueString(a->first), a->second, e->second); |
|
2277 return false; |
|
2278 } |
|
2279 // Don't complain if this doesn't recover all registers. Although |
|
2280 // the DWARF spec says that unmentioned registers are undefined, |
|
2281 // GCC uses omission to mean that they are unchanged. |
|
2282 } |
|
2283 return true; |
|
2284 } |
|
2285 @@ -254,81 +263,81 @@ |
|
2286 |
|
2287 CFIFrameInfo::RegisterValueMap<uint32_t> current_registers; |
|
2288 CFIFrameInfo::RegisterValueMap<uint32_t> caller_registers; |
|
2289 CFIFrameInfo::RegisterValueMap<uint32_t> expected_caller_registers; |
|
2290 MockMemoryRegion memory; |
|
2291 |
|
2292 // Regardless of which instruction evaluation takes place at, it |
|
2293 // should produce the same values for the caller's registers. |
|
2294 - expected_caller_registers[".cfa"] = 0x1001c; |
|
2295 - expected_caller_registers[".ra"] = 0xf6438648; |
|
2296 - expected_caller_registers["$ebp"] = 0x10038; |
|
2297 - expected_caller_registers["$ebx"] = 0x98ecadc3; |
|
2298 - expected_caller_registers["$esi"] = 0x878f7524; |
|
2299 - expected_caller_registers["$edi"] = 0x6312f9a5; |
|
2300 + expected_caller_registers[ustr__ZDcfa()] = 0x1001c; |
|
2301 + expected_caller_registers[ustr__ZDra()] = 0xf6438648; |
|
2302 + expected_caller_registers[ustr__ZSebp()] = 0x10038; |
|
2303 + expected_caller_registers[ustr__ZSebx()] = 0x98ecadc3; |
|
2304 + expected_caller_registers[ustr__ZSesi()] = 0x878f7524; |
|
2305 + expected_caller_registers[ustr__ZSedi()] = 0x6312f9a5; |
|
2306 |
|
2307 frame.instruction = 0x3d40; |
|
2308 frame.module = &module1; |
|
2309 current_registers.clear(); |
|
2310 - current_registers["$esp"] = 0x10018; |
|
2311 - current_registers["$ebp"] = 0x10038; |
|
2312 - current_registers["$ebx"] = 0x98ecadc3; |
|
2313 - current_registers["$esi"] = 0x878f7524; |
|
2314 - current_registers["$edi"] = 0x6312f9a5; |
|
2315 + current_registers[ustr__ZSesp()] = 0x10018; |
|
2316 + current_registers[ustr__ZSebp()] = 0x10038; |
|
2317 + current_registers[ustr__ZSebx()] = 0x98ecadc3; |
|
2318 + current_registers[ustr__ZSesi()] = 0x878f7524; |
|
2319 + current_registers[ustr__ZSedi()] = 0x6312f9a5; |
|
2320 cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); |
|
2321 ASSERT_TRUE(cfi_frame_info.get()); |
|
2322 ASSERT_TRUE(cfi_frame_info.get() |
|
2323 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
2324 &caller_registers)); |
|
2325 ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__, |
|
2326 expected_caller_registers, caller_registers)); |
|
2327 |
|
2328 frame.instruction = 0x3d41; |
|
2329 - current_registers["$esp"] = 0x10014; |
|
2330 + current_registers[ustr__ZSesp()] = 0x10014; |
|
2331 cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); |
|
2332 ASSERT_TRUE(cfi_frame_info.get()); |
|
2333 ASSERT_TRUE(cfi_frame_info.get() |
|
2334 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
2335 &caller_registers)); |
|
2336 ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__, |
|
2337 expected_caller_registers, caller_registers)); |
|
2338 |
|
2339 frame.instruction = 0x3d43; |
|
2340 - current_registers["$ebp"] = 0x10014; |
|
2341 + current_registers[ustr__ZSebp()] = 0x10014; |
|
2342 cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); |
|
2343 ASSERT_TRUE(cfi_frame_info.get()); |
|
2344 ASSERT_TRUE(cfi_frame_info.get() |
|
2345 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
2346 &caller_registers)); |
|
2347 VerifyRegisters(__FILE__, __LINE__, |
|
2348 expected_caller_registers, caller_registers); |
|
2349 |
|
2350 frame.instruction = 0x3d54; |
|
2351 - current_registers["$ebx"] = 0x6864f054U; |
|
2352 + current_registers[ustr__ZSebx()] = 0x6864f054U; |
|
2353 cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); |
|
2354 ASSERT_TRUE(cfi_frame_info.get()); |
|
2355 ASSERT_TRUE(cfi_frame_info.get() |
|
2356 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
2357 &caller_registers)); |
|
2358 VerifyRegisters(__FILE__, __LINE__, |
|
2359 expected_caller_registers, caller_registers); |
|
2360 |
|
2361 frame.instruction = 0x3d5a; |
|
2362 - current_registers["$esi"] = 0x6285f79aU; |
|
2363 + current_registers[ustr__ZSesi()] = 0x6285f79aU; |
|
2364 cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); |
|
2365 ASSERT_TRUE(cfi_frame_info.get()); |
|
2366 ASSERT_TRUE(cfi_frame_info.get() |
|
2367 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
2368 &caller_registers)); |
|
2369 VerifyRegisters(__FILE__, __LINE__, |
|
2370 expected_caller_registers, caller_registers); |
|
2371 |
|
2372 frame.instruction = 0x3d84; |
|
2373 - current_registers["$edi"] = 0x64061449U; |
|
2374 + current_registers[ustr__ZSedi()] = 0x64061449U; |
|
2375 cfi_frame_info.reset(resolver.FindCFIFrameInfo(&frame)); |
|
2376 ASSERT_TRUE(cfi_frame_info.get()); |
|
2377 ASSERT_TRUE(cfi_frame_info.get() |
|
2378 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
2379 &caller_registers)); |
|
2380 VerifyRegisters(__FILE__, __LINE__, |
|
2381 expected_caller_registers, caller_registers); |
|
2382 |
|
2383 diff --git a/src/processor/cfi_frame_info.cc b/src/processor/cfi_frame_info.cc |
|
2384 --- a/src/processor/cfi_frame_info.cc |
|
2385 +++ b/src/processor/cfi_frame_info.cc |
|
2386 @@ -31,16 +31,17 @@ |
|
2387 |
|
2388 // cfi_frame_info.cc: Implementation of CFIFrameInfo class. |
|
2389 // See cfi_frame_info.h for details. |
|
2390 |
|
2391 #include "processor/cfi_frame_info.h" |
|
2392 |
|
2393 #include <string.h> |
|
2394 |
|
2395 +#include <algorithm> |
|
2396 #include <sstream> |
|
2397 |
|
2398 #include "common/scoped_ptr.h" |
|
2399 #include "processor/postfix_evaluator-inl.h" |
|
2400 |
|
2401 namespace google_breakpad { |
|
2402 |
|
2403 #ifdef _WIN32 |
|
2404 @@ -65,33 +66,33 @@ |
|
2405 V cfa; |
|
2406 working = registers; |
|
2407 if (!evaluator.EvaluateForValue(cfa_rule_, &cfa)) |
|
2408 return false; |
|
2409 |
|
2410 // Then, compute the return address. |
|
2411 V ra; |
|
2412 working = registers; |
|
2413 - working[".cfa"] = cfa; |
|
2414 + working[ustr__ZDcfa()] = cfa; |
|
2415 if (!evaluator.EvaluateForValue(ra_rule_, &ra)) |
|
2416 return false; |
|
2417 |
|
2418 // Now, compute values for all the registers register_rules_ mentions. |
|
2419 for (RuleMap::const_iterator it = register_rules_.begin(); |
|
2420 it != register_rules_.end(); it++) { |
|
2421 V value; |
|
2422 working = registers; |
|
2423 - working[".cfa"] = cfa; |
|
2424 + working[ustr__ZDcfa()] = cfa; |
|
2425 if (!evaluator.EvaluateForValue(it->second, &value)) |
|
2426 return false; |
|
2427 (*caller_registers)[it->first] = value; |
|
2428 } |
|
2429 |
|
2430 - (*caller_registers)[".ra"] = ra; |
|
2431 - (*caller_registers)[".cfa"] = cfa; |
|
2432 + (*caller_registers)[ustr__ZDra()] = ra; |
|
2433 + (*caller_registers)[ustr__ZDcfa()] = cfa; |
|
2434 |
|
2435 return true; |
|
2436 } |
|
2437 |
|
2438 // Explicit instantiations for 32-bit and 64-bit architectures. |
|
2439 template bool CFIFrameInfo::FindCallerRegs<uint32_t>( |
|
2440 const RegisterValueMap<uint32_t> ®isters, |
|
2441 const MemoryRegion &memory, |
|
2442 @@ -107,81 +108,98 @@ |
|
2443 if (!cfa_rule_.invalid()) { |
|
2444 stream << ".cfa: " << cfa_rule_; |
|
2445 } |
|
2446 if (!ra_rule_.invalid()) { |
|
2447 if (static_cast<std::streamoff>(stream.tellp()) != 0) |
|
2448 stream << " "; |
|
2449 stream << ".ra: " << ra_rule_; |
|
2450 } |
|
2451 + |
|
2452 + // Visit the register rules in alphabetical order. Because |
|
2453 + // register_rules_ has the elements in some arbitrary order, |
|
2454 + // get the names out into a vector, sort them, and visit in |
|
2455 + // sorted order. |
|
2456 + std::vector<const UniqueString*> rr_names; |
|
2457 for (RuleMap::const_iterator iter = register_rules_.begin(); |
|
2458 iter != register_rules_.end(); |
|
2459 ++iter) { |
|
2460 + rr_names.push_back(iter->first); |
|
2461 + } |
|
2462 + |
|
2463 + std::sort(rr_names.begin(), rr_names.end(), LessThan_UniqueString); |
|
2464 + |
|
2465 + // Now visit the register rules in alphabetical order. |
|
2466 + for (std::vector<const UniqueString*>::const_iterator name = rr_names.begin(); |
|
2467 + name != rr_names.end(); |
|
2468 + ++name) { |
|
2469 + const UniqueString* nm = *name; |
|
2470 + Module::Expr rule = register_rules_.find(nm)->second; |
|
2471 if (static_cast<std::streamoff>(stream.tellp()) != 0) |
|
2472 stream << " "; |
|
2473 - stream << iter->first << ": " << iter->second; |
|
2474 + stream << FromUniqueString(nm) << ": " << rule; |
|
2475 } |
|
2476 |
|
2477 return stream.str(); |
|
2478 } |
|
2479 |
|
2480 bool CFIRuleParser::Parse(const string &rule_set) { |
|
2481 size_t rule_set_len = rule_set.size(); |
|
2482 scoped_array<char> working_copy(new char[rule_set_len + 1]); |
|
2483 memcpy(working_copy.get(), rule_set.data(), rule_set_len); |
|
2484 working_copy[rule_set_len] = '\0'; |
|
2485 |
|
2486 - name_.clear(); |
|
2487 + name_ = ustr__empty(); |
|
2488 expression_.clear(); |
|
2489 |
|
2490 char *cursor; |
|
2491 static const char token_breaks[] = " \t\r\n"; |
|
2492 char *token = strtok_r(working_copy.get(), token_breaks, &cursor); |
|
2493 |
|
2494 for (;;) { |
|
2495 // End of rule set? |
|
2496 if (!token) return Report(); |
|
2497 |
|
2498 // Register/pseudoregister name? |
|
2499 size_t token_len = strlen(token); |
|
2500 if (token_len >= 1 && token[token_len - 1] == ':') { |
|
2501 // Names can't be empty. |
|
2502 if (token_len < 2) return false; |
|
2503 // If there is any pending content, report it. |
|
2504 - if (!name_.empty() || !expression_.empty()) { |
|
2505 + if (name_ != ustr__empty() || !expression_.empty()) { |
|
2506 if (!Report()) return false; |
|
2507 } |
|
2508 - name_.assign(token, token_len - 1); |
|
2509 + name_ = ToUniqueString_n(token, token_len - 1); |
|
2510 expression_.clear(); |
|
2511 } else { |
|
2512 // Another expression component. |
|
2513 assert(token_len > 0); // strtok_r guarantees this, I think. |
|
2514 if (!expression_.empty()) |
|
2515 expression_ += ' '; |
|
2516 expression_ += token; |
|
2517 } |
|
2518 token = strtok_r(NULL, token_breaks, &cursor); |
|
2519 } |
|
2520 } |
|
2521 |
|
2522 bool CFIRuleParser::Report() { |
|
2523 - if (name_.empty() || expression_.empty()) return false; |
|
2524 - if (name_ == ".cfa") handler_->CFARule(expression_); |
|
2525 - else if (name_ == ".ra") handler_->RARule(expression_); |
|
2526 + if (name_ == ustr__empty() || expression_.empty()) return false; |
|
2527 + if (name_ == ustr__ZDcfa()) handler_->CFARule(expression_); |
|
2528 + else if (name_ == ustr__ZDra()) handler_->RARule(expression_); |
|
2529 else handler_->RegisterRule(name_, expression_); |
|
2530 return true; |
|
2531 } |
|
2532 |
|
2533 void CFIFrameInfoParseHandler::CFARule(const string &expression) { |
|
2534 // 'expression' is a postfix expression string. |
|
2535 frame_info_->SetCFARule(Module::Expr(expression)); |
|
2536 } |
|
2537 |
|
2538 void CFIFrameInfoParseHandler::RARule(const string &expression) { |
|
2539 frame_info_->SetRARule(Module::Expr(expression)); |
|
2540 } |
|
2541 |
|
2542 -void CFIFrameInfoParseHandler::RegisterRule(const string &name, |
|
2543 +void CFIFrameInfoParseHandler::RegisterRule(const UniqueString* name, |
|
2544 const string &expression) { |
|
2545 frame_info_->SetRegisterRule(name, Module::Expr(expression)); |
|
2546 } |
|
2547 |
|
2548 } // namespace google_breakpad |
|
2549 diff --git a/src/processor/cfi_frame_info.h b/src/processor/cfi_frame_info.h |
|
2550 --- a/src/processor/cfi_frame_info.h |
|
2551 +++ b/src/processor/cfi_frame_info.h |
|
2552 @@ -37,16 +37,17 @@ |
|
2553 |
|
2554 #ifndef PROCESSOR_CFI_FRAME_INFO_H_ |
|
2555 #define PROCESSOR_CFI_FRAME_INFO_H_ |
|
2556 |
|
2557 #include <map> |
|
2558 #include <string> |
|
2559 |
|
2560 #include "common/using_std_string.h" |
|
2561 +#include "common/unique_string.h" |
|
2562 #include "google_breakpad/common/breakpad_types.h" |
|
2563 #include "common/module.h" |
|
2564 |
|
2565 namespace google_breakpad { |
|
2566 |
|
2567 using std::map; |
|
2568 |
|
2569 class MemoryRegion; |
|
2570 @@ -63,24 +64,24 @@ |
|
2571 // changes given by the 'STACK CFI' records up to our instruction's |
|
2572 // address. Then, use the FindCallerRegs member function to apply the |
|
2573 // rules to the callee frame's register values, yielding the caller |
|
2574 // frame's register values. |
|
2575 class CFIFrameInfo { |
|
2576 public: |
|
2577 // A map from register names onto values. |
|
2578 template<typename ValueType> class RegisterValueMap: |
|
2579 - public map<string, ValueType> { }; |
|
2580 + public map<const UniqueString*, ValueType> { }; |
|
2581 |
|
2582 // Set the expression for computing a call frame address, return |
|
2583 // address, or register's value. At least the CFA rule and the RA |
|
2584 // rule must be set before calling FindCallerRegs. |
|
2585 void SetCFARule(const Module::Expr& rule) { cfa_rule_ = rule; } |
|
2586 void SetRARule(const Module::Expr& rule) { ra_rule_ = rule; } |
|
2587 - void SetRegisterRule(const string& register_name, |
|
2588 + void SetRegisterRule(const UniqueString* register_name, |
|
2589 const Module::Expr& rule) { |
|
2590 register_rules_[register_name] = rule; |
|
2591 } |
|
2592 |
|
2593 // Compute the values of the calling frame's registers, according to |
|
2594 // this rule set. Use ValueType in expression evaluation; this |
|
2595 // should be uint32_t on machines with 32-bit addresses, or |
|
2596 // uint64_t on machines with 64-bit addresses. |
|
2597 @@ -104,17 +105,17 @@ |
|
2598 |
|
2599 // Serialize the rules in this object into a string in the format |
|
2600 // of STACK CFI records. |
|
2601 string Serialize() const; |
|
2602 |
|
2603 private: |
|
2604 |
|
2605 // A map from register names onto evaluation rules. |
|
2606 - typedef map<string, Module::Expr> RuleMap; |
|
2607 + typedef map<const UniqueString*, Module::Expr> RuleMap; |
|
2608 |
|
2609 // An expression for computing the current frame's CFA (call |
|
2610 // frame address). The CFA is a reference address for the frame that |
|
2611 // remains unchanged throughout the frame's lifetime. You should |
|
2612 // evaluate this expression with a dictionary initially populated |
|
2613 // with the values of the current frame's known registers. |
|
2614 Module::Expr cfa_rule_; |
|
2615 |
|
2616 @@ -145,17 +146,18 @@ |
|
2617 Handler() { } |
|
2618 virtual ~Handler() { } |
|
2619 |
|
2620 // The input specifies EXPRESSION as the CFA/RA computation rule. |
|
2621 virtual void CFARule(const string &expression) = 0; |
|
2622 virtual void RARule(const string &expression) = 0; |
|
2623 |
|
2624 // The input specifies EXPRESSION as the recovery rule for register NAME. |
|
2625 - virtual void RegisterRule(const string &name, const string &expression) = 0; |
|
2626 + virtual void RegisterRule(const UniqueString* name, |
|
2627 + const string &expression) = 0; |
|
2628 }; |
|
2629 |
|
2630 // Construct a parser which feeds its results to HANDLER. |
|
2631 CFIRuleParser(Handler *handler) : handler_(handler) { } |
|
2632 |
|
2633 // Parse RULE_SET as a set of CFA computation and RA/register |
|
2634 // recovery rules, as appearing in STACK CFI records. Report the |
|
2635 // results of parsing by making the appropriate calls to handler_. |
|
2636 @@ -165,30 +167,31 @@ |
|
2637 private: |
|
2638 // Report any accumulated rule to handler_ |
|
2639 bool Report(); |
|
2640 |
|
2641 // The handler to which the parser reports its findings. |
|
2642 Handler *handler_; |
|
2643 |
|
2644 // Working data. |
|
2645 - string name_, expression_; |
|
2646 + const UniqueString* name_; |
|
2647 + string expression_; |
|
2648 }; |
|
2649 |
|
2650 // A handler for rule set parsing that populates a CFIFrameInfo with |
|
2651 // the results. |
|
2652 class CFIFrameInfoParseHandler: public CFIRuleParser::Handler { |
|
2653 public: |
|
2654 // Populate FRAME_INFO with the results of parsing. |
|
2655 CFIFrameInfoParseHandler(CFIFrameInfo *frame_info) |
|
2656 : frame_info_(frame_info) { } |
|
2657 |
|
2658 void CFARule(const string &expression); |
|
2659 void RARule(const string &expression); |
|
2660 - void RegisterRule(const string &name, const string &expression); |
|
2661 + void RegisterRule(const UniqueString* name, const string &expression); |
|
2662 |
|
2663 private: |
|
2664 CFIFrameInfo *frame_info_; |
|
2665 }; |
|
2666 |
|
2667 // A utility class template for simple 'STACK CFI'-driven stack walkers. |
|
2668 // Given a CFIFrameInfo instance, a table describing the architecture's |
|
2669 // register set, and a context holding the last frame's registers, an |
|
2670 @@ -205,24 +208,24 @@ |
|
2671 // uint32_t or uint64_t. RawContextType should be the raw context |
|
2672 // structure type for this architecture. |
|
2673 template <typename RegisterType, class RawContextType> |
|
2674 class SimpleCFIWalker { |
|
2675 public: |
|
2676 // A structure describing one architecture register. |
|
2677 struct RegisterSet { |
|
2678 // The register name, as it appears in STACK CFI rules. |
|
2679 - const char *name; |
|
2680 + const UniqueString* name; |
|
2681 |
|
2682 // An alternate name that the register's value might be found |
|
2683 // under in a register value dictionary, or NULL. When generating |
|
2684 // names, prefer NAME to this value. It's common to list ".cfa" as |
|
2685 // an alternative name for the stack pointer, and ".ra" as an |
|
2686 // alternative name for the instruction pointer. |
|
2687 - const char *alternate_name; |
|
2688 + const UniqueString* alternate_name; |
|
2689 |
|
2690 // True if the callee is expected to preserve the value of this |
|
2691 // register. If this flag is true for some register R, and the STACK |
|
2692 // CFI records provide no rule to recover R, then SimpleCFIWalker |
|
2693 // assumes that the callee has not changed R's value, and the caller's |
|
2694 // value for R is that currently in the callee's context. |
|
2695 bool callee_saves; |
|
2696 |
|
2697 diff --git a/src/processor/cfi_frame_info_unittest.cc b/src/processor/cfi_frame_info_unittest.cc |
|
2698 --- a/src/processor/cfi_frame_info_unittest.cc |
|
2699 +++ b/src/processor/cfi_frame_info_unittest.cc |
|
2700 @@ -38,19 +38,24 @@ |
|
2701 #include "common/module.h" |
|
2702 #include "common/using_std_string.h" |
|
2703 #include "processor/cfi_frame_info.h" |
|
2704 #include "google_breakpad/processor/memory_region.h" |
|
2705 |
|
2706 using google_breakpad::CFIFrameInfo; |
|
2707 using google_breakpad::CFIFrameInfoParseHandler; |
|
2708 using google_breakpad::CFIRuleParser; |
|
2709 +using google_breakpad::FromUniqueString; |
|
2710 using google_breakpad::MemoryRegion; |
|
2711 using google_breakpad::Module; |
|
2712 using google_breakpad::SimpleCFIWalker; |
|
2713 +using google_breakpad::ToUniqueString; |
|
2714 +using google_breakpad::UniqueString; |
|
2715 +using google_breakpad::ustr__ZDcfa; |
|
2716 +using google_breakpad::ustr__ZDra; |
|
2717 using testing::_; |
|
2718 using testing::A; |
|
2719 using testing::AtMost; |
|
2720 using testing::DoAll; |
|
2721 using testing::Return; |
|
2722 using testing::SetArgumentPointee; |
|
2723 using testing::Test; |
|
2724 |
|
2725 @@ -107,41 +112,47 @@ |
|
2726 TEST_F(Simple, SetCFAAndRARule) { |
|
2727 ExpectNoMemoryReferences(); |
|
2728 |
|
2729 cfi.SetCFARule(Module::Expr("330903416631436410")); |
|
2730 cfi.SetRARule(Module::Expr("5870666104170902211")); |
|
2731 ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
2732 &caller_registers)); |
|
2733 ASSERT_EQ(2U, caller_registers.size()); |
|
2734 - ASSERT_EQ(330903416631436410ULL, caller_registers[".cfa"]); |
|
2735 - ASSERT_EQ(5870666104170902211ULL, caller_registers[".ra"]); |
|
2736 + ASSERT_EQ(330903416631436410ULL, caller_registers[ustr__ZDcfa()]); |
|
2737 + ASSERT_EQ(5870666104170902211ULL, caller_registers[ustr__ZDra()]); |
|
2738 |
|
2739 ASSERT_EQ(".cfa: 330903416631436410 .ra: 5870666104170902211", |
|
2740 cfi.Serialize()); |
|
2741 } |
|
2742 |
|
2743 TEST_F(Simple, SetManyRules) { |
|
2744 ExpectNoMemoryReferences(); |
|
2745 |
|
2746 cfi.SetCFARule(Module::Expr("$temp1 68737028 = $temp2 61072337 = $temp1 $temp2 -")); |
|
2747 cfi.SetRARule(Module::Expr(".cfa 99804755 +")); |
|
2748 - cfi.SetRegisterRule("register1", Module::Expr(".cfa 54370437 *")); |
|
2749 - cfi.SetRegisterRule("vodkathumbscrewingly", Module::Expr("24076308 .cfa +")); |
|
2750 - cfi.SetRegisterRule("pubvexingfjordschmaltzy", Module::Expr(".cfa 29801007 -")); |
|
2751 - cfi.SetRegisterRule("uncopyrightables", Module::Expr("92642917 .cfa /")); |
|
2752 + |
|
2753 + const UniqueString* reg1 = ToUniqueString("register1"); |
|
2754 + const UniqueString* reg2 = ToUniqueString("vodkathumbscrewingly"); |
|
2755 + const UniqueString* reg3 = ToUniqueString("pubvexingfjordschmaltzy"); |
|
2756 + const UniqueString* reg4 = ToUniqueString("uncopyrightables"); |
|
2757 + |
|
2758 + cfi.SetRegisterRule(reg1, Module::Expr(".cfa 54370437 *")); |
|
2759 + cfi.SetRegisterRule(reg2, Module::Expr("24076308 .cfa +")); |
|
2760 + cfi.SetRegisterRule(reg3, Module::Expr(".cfa 29801007 -")); |
|
2761 + cfi.SetRegisterRule(reg4, Module::Expr("92642917 .cfa /")); |
|
2762 ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
2763 &caller_registers)); |
|
2764 ASSERT_EQ(6U, caller_registers.size()); |
|
2765 - ASSERT_EQ(7664691U, caller_registers[".cfa"]); |
|
2766 - ASSERT_EQ(107469446U, caller_registers[".ra"]); |
|
2767 - ASSERT_EQ(416732599139967ULL, caller_registers["register1"]); |
|
2768 - ASSERT_EQ(31740999U, caller_registers["vodkathumbscrewingly"]); |
|
2769 - ASSERT_EQ(-22136316ULL, caller_registers["pubvexingfjordschmaltzy"]); |
|
2770 - ASSERT_EQ(12U, caller_registers["uncopyrightables"]); |
|
2771 + ASSERT_EQ(7664691U, caller_registers[ustr__ZDcfa()]); |
|
2772 + ASSERT_EQ(107469446U, caller_registers[ustr__ZDra()]); |
|
2773 + ASSERT_EQ(416732599139967ULL, caller_registers[reg1]); |
|
2774 + ASSERT_EQ(31740999U, caller_registers[reg2]); |
|
2775 + ASSERT_EQ(-22136316ULL, caller_registers[reg3]); |
|
2776 + ASSERT_EQ(12U, caller_registers[reg4]); |
|
2777 ASSERT_EQ(".cfa: $temp1 68737028 = $temp2 61072337 = $temp1 $temp2 - " |
|
2778 ".ra: .cfa 99804755 + " |
|
2779 "pubvexingfjordschmaltzy: .cfa 29801007 - " |
|
2780 "register1: .cfa 54370437 * " |
|
2781 "uncopyrightables: 92642917 .cfa / " |
|
2782 "vodkathumbscrewingly: 24076308 .cfa +", |
|
2783 cfi.Serialize()); |
|
2784 } |
|
2785 @@ -150,18 +161,18 @@ |
|
2786 ExpectNoMemoryReferences(); |
|
2787 |
|
2788 cfi.SetCFARule(Module::Expr("330903416631436410")); |
|
2789 cfi.SetRARule(Module::Expr("5870666104170902211")); |
|
2790 cfi.SetCFARule(Module::Expr("2828089117179001")); |
|
2791 ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
2792 &caller_registers)); |
|
2793 ASSERT_EQ(2U, caller_registers.size()); |
|
2794 - ASSERT_EQ(2828089117179001ULL, caller_registers[".cfa"]); |
|
2795 - ASSERT_EQ(5870666104170902211ULL, caller_registers[".ra"]); |
|
2796 + ASSERT_EQ(2828089117179001ULL, caller_registers[ustr__ZDcfa()]); |
|
2797 + ASSERT_EQ(5870666104170902211ULL, caller_registers[ustr__ZDra()]); |
|
2798 ASSERT_EQ(".cfa: 2828089117179001 .ra: 5870666104170902211", |
|
2799 cfi.Serialize()); |
|
2800 } |
|
2801 |
|
2802 class Scope: public CFIFixture, public Test { }; |
|
2803 |
|
2804 // There should be no value for .cfa in scope when evaluating the CFA rule. |
|
2805 TEST_F(Scope, CFALacksCFA) { |
|
2806 @@ -183,37 +194,39 @@ |
|
2807 &caller_registers)); |
|
2808 } |
|
2809 |
|
2810 // The current frame's registers should be in scope when evaluating |
|
2811 // the CFA rule. |
|
2812 TEST_F(Scope, CFASeesCurrentRegs) { |
|
2813 ExpectNoMemoryReferences(); |
|
2814 |
|
2815 - registers[".baraminology"] = 0x06a7bc63e4f13893ULL; |
|
2816 - registers[".ornithorhynchus"] = 0x5e0bf850bafce9d2ULL; |
|
2817 + const UniqueString* reg1 = ToUniqueString(".baraminology"); |
|
2818 + const UniqueString* reg2 = ToUniqueString(".ornithorhynchus"); |
|
2819 + registers[reg1] = 0x06a7bc63e4f13893ULL; |
|
2820 + registers[reg2] = 0x5e0bf850bafce9d2ULL; |
|
2821 cfi.SetCFARule(Module::Expr(".baraminology .ornithorhynchus +")); |
|
2822 cfi.SetRARule(Module::Expr("0")); |
|
2823 ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
2824 &caller_registers)); |
|
2825 ASSERT_EQ(2U, caller_registers.size()); |
|
2826 ASSERT_EQ(0x06a7bc63e4f13893ULL + 0x5e0bf850bafce9d2ULL, |
|
2827 - caller_registers[".cfa"]); |
|
2828 + caller_registers[ustr__ZDcfa()]); |
|
2829 } |
|
2830 |
|
2831 // .cfa should be in scope in the return address expression. |
|
2832 TEST_F(Scope, RASeesCFA) { |
|
2833 ExpectNoMemoryReferences(); |
|
2834 |
|
2835 cfi.SetCFARule(Module::Expr("48364076")); |
|
2836 cfi.SetRARule(Module::Expr(".cfa")); |
|
2837 ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
2838 &caller_registers)); |
|
2839 ASSERT_EQ(2U, caller_registers.size()); |
|
2840 - ASSERT_EQ(48364076U, caller_registers[".ra"]); |
|
2841 + ASSERT_EQ(48364076U, caller_registers[ustr__ZDra()]); |
|
2842 } |
|
2843 |
|
2844 // There should be no value for .ra in scope when evaluating the CFA rule. |
|
2845 TEST_F(Scope, RALacksRA) { |
|
2846 ExpectNoMemoryReferences(); |
|
2847 |
|
2848 cfi.SetCFARule(Module::Expr("0")); |
|
2849 cfi.SetRARule(Module::Expr(".ra")); |
|
2850 @@ -221,64 +234,69 @@ |
|
2851 &caller_registers)); |
|
2852 } |
|
2853 |
|
2854 // The current frame's registers should be in scope in the return |
|
2855 // address expression. |
|
2856 TEST_F(Scope, RASeesCurrentRegs) { |
|
2857 ExpectNoMemoryReferences(); |
|
2858 |
|
2859 - registers["noachian"] = 0x54dc4a5d8e5eb503ULL; |
|
2860 cfi.SetCFARule(Module::Expr("10359370")); |
|
2861 - cfi.SetRARule(Module::Expr("noachian")); |
|
2862 + const UniqueString* reg1 = ToUniqueString("noachian"); |
|
2863 + registers[reg1] = 0x54dc4a5d8e5eb503ULL; |
|
2864 + cfi.SetRARule(Module::Expr(reg1, 0, false)); |
|
2865 ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
2866 &caller_registers)); |
|
2867 ASSERT_EQ(2U, caller_registers.size()); |
|
2868 - ASSERT_EQ(0x54dc4a5d8e5eb503ULL, caller_registers[".ra"]); |
|
2869 + ASSERT_EQ(0x54dc4a5d8e5eb503ULL, caller_registers[ustr__ZDra()]); |
|
2870 } |
|
2871 |
|
2872 // .cfa should be in scope for register rules. |
|
2873 TEST_F(Scope, RegistersSeeCFA) { |
|
2874 ExpectNoMemoryReferences(); |
|
2875 |
|
2876 cfi.SetCFARule(Module::Expr("6515179")); |
|
2877 cfi.SetRARule(Module::Expr(".cfa")); |
|
2878 - cfi.SetRegisterRule("rogerian", Module::Expr(".cfa")); |
|
2879 + const UniqueString* reg1 = ToUniqueString("rogerian"); |
|
2880 + cfi.SetRegisterRule(reg1, Module::Expr(".cfa")); |
|
2881 ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
2882 &caller_registers)); |
|
2883 ASSERT_EQ(3U, caller_registers.size()); |
|
2884 - ASSERT_EQ(6515179U, caller_registers["rogerian"]); |
|
2885 + ASSERT_EQ(6515179U, caller_registers[reg1]); |
|
2886 } |
|
2887 |
|
2888 // The return address should not be in scope for register rules. |
|
2889 TEST_F(Scope, RegsLackRA) { |
|
2890 ExpectNoMemoryReferences(); |
|
2891 |
|
2892 cfi.SetCFARule(Module::Expr("42740329")); |
|
2893 cfi.SetRARule(Module::Expr("27045204")); |
|
2894 - cfi.SetRegisterRule("$r1", Module::Expr(".ra")); |
|
2895 + const UniqueString* reg1 = ToUniqueString("$r1"); |
|
2896 + cfi.SetRegisterRule(reg1, Module::Expr(".ra")); |
|
2897 ASSERT_FALSE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
2898 &caller_registers)); |
|
2899 } |
|
2900 |
|
2901 // Register rules can see the current frame's register values. |
|
2902 TEST_F(Scope, RegsSeeRegs) { |
|
2903 ExpectNoMemoryReferences(); |
|
2904 |
|
2905 - registers["$r1"] = 0x6ed3582c4bedb9adULL; |
|
2906 - registers["$r2"] = 0xd27d9e742b8df6d0ULL; |
|
2907 + const UniqueString* reg1 = ToUniqueString("$r1"); |
|
2908 + const UniqueString* reg2 = ToUniqueString("$r2"); |
|
2909 + registers[reg1] = 0x6ed3582c4bedb9adULL; |
|
2910 + registers[reg2] = 0xd27d9e742b8df6d0ULL; |
|
2911 cfi.SetCFARule(Module::Expr("88239303")); |
|
2912 cfi.SetRARule(Module::Expr("30503835")); |
|
2913 - cfi.SetRegisterRule("$r1", Module::Expr("$r1 42175211 = $r2")); |
|
2914 - cfi.SetRegisterRule("$r2", Module::Expr("$r2 21357221 = $r1")); |
|
2915 + cfi.SetRegisterRule(reg1, Module::Expr("$r1 42175211 = $r2")); |
|
2916 + cfi.SetRegisterRule(reg2, Module::Expr("$r2 21357221 = $r1")); |
|
2917 ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
2918 &caller_registers)); |
|
2919 ASSERT_EQ(4U, caller_registers.size()); |
|
2920 - ASSERT_EQ(0xd27d9e742b8df6d0ULL, caller_registers["$r1"]); |
|
2921 - ASSERT_EQ(0x6ed3582c4bedb9adULL, caller_registers["$r2"]); |
|
2922 + ASSERT_EQ(0xd27d9e742b8df6d0ULL, caller_registers[reg1]); |
|
2923 + ASSERT_EQ(0x6ed3582c4bedb9adULL, caller_registers[reg2]); |
|
2924 } |
|
2925 |
|
2926 // Each rule's temporaries are separate. |
|
2927 TEST_F(Scope, SeparateTempsRA) { |
|
2928 ExpectNoMemoryReferences(); |
|
2929 |
|
2930 cfi.SetCFARule(Module::Expr("$temp1 76569129 = $temp1")); |
|
2931 cfi.SetRARule(Module::Expr("0")); |
|
2932 @@ -290,17 +308,17 @@ |
|
2933 ASSERT_FALSE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
2934 &caller_registers)); |
|
2935 } |
|
2936 |
|
2937 class MockCFIRuleParserHandler: public CFIRuleParser::Handler { |
|
2938 public: |
|
2939 MOCK_METHOD1(CFARule, void(const string &)); |
|
2940 MOCK_METHOD1(RARule, void(const string &)); |
|
2941 - MOCK_METHOD2(RegisterRule, void(const string &, const string &)); |
|
2942 + MOCK_METHOD2(RegisterRule, void(const UniqueString*, const string &)); |
|
2943 }; |
|
2944 |
|
2945 // A fixture class for testing CFIRuleParser. |
|
2946 class CFIParserFixture { |
|
2947 public: |
|
2948 CFIParserFixture() : parser(&mock_handler) { |
|
2949 // Expect no parsing results to be reported to mock_handler. Individual |
|
2950 // tests can override this. |
|
2951 @@ -361,100 +379,100 @@ |
|
2952 } |
|
2953 |
|
2954 TEST_F(Parser, RA) { |
|
2955 EXPECT_CALL(mock_handler, RARule("notoriety")).WillOnce(Return()); |
|
2956 EXPECT_TRUE(parser.Parse(".ra: notoriety")); |
|
2957 } |
|
2958 |
|
2959 TEST_F(Parser, Reg) { |
|
2960 - EXPECT_CALL(mock_handler, RegisterRule("nemo", "mellifluous")) |
|
2961 + EXPECT_CALL(mock_handler, RegisterRule(ToUniqueString("nemo"), "mellifluous")) |
|
2962 .WillOnce(Return()); |
|
2963 EXPECT_TRUE(parser.Parse("nemo: mellifluous")); |
|
2964 } |
|
2965 |
|
2966 TEST_F(Parser, CFARARegs) { |
|
2967 EXPECT_CALL(mock_handler, CFARule("cfa expression")).WillOnce(Return()); |
|
2968 EXPECT_CALL(mock_handler, RARule("ra expression")).WillOnce(Return()); |
|
2969 - EXPECT_CALL(mock_handler, RegisterRule("galba", "praetorian")) |
|
2970 + EXPECT_CALL(mock_handler, RegisterRule(ToUniqueString("galba"), "praetorian")) |
|
2971 .WillOnce(Return()); |
|
2972 - EXPECT_CALL(mock_handler, RegisterRule("otho", "vitellius")) |
|
2973 + EXPECT_CALL(mock_handler, RegisterRule(ToUniqueString("otho"), "vitellius")) |
|
2974 .WillOnce(Return()); |
|
2975 EXPECT_TRUE(parser.Parse(".cfa: cfa expression .ra: ra expression " |
|
2976 "galba: praetorian otho: vitellius")); |
|
2977 } |
|
2978 |
|
2979 TEST_F(Parser, Whitespace) { |
|
2980 - EXPECT_CALL(mock_handler, RegisterRule("r1", "r1 expression")) |
|
2981 + EXPECT_CALL(mock_handler, RegisterRule(ToUniqueString("r1"), "r1 expression")) |
|
2982 .WillOnce(Return()); |
|
2983 - EXPECT_CALL(mock_handler, RegisterRule("r2", "r2 expression")) |
|
2984 + EXPECT_CALL(mock_handler, RegisterRule(ToUniqueString("r2"), "r2 expression")) |
|
2985 .WillOnce(Return()); |
|
2986 EXPECT_TRUE(parser.Parse(" r1:\tr1\nexpression \tr2:\t\rr2\r\n " |
|
2987 "expression \n")); |
|
2988 } |
|
2989 |
|
2990 TEST_F(Parser, WhitespaceLoneColon) { |
|
2991 EXPECT_FALSE(parser.Parse(" \n:\t ")); |
|
2992 } |
|
2993 |
|
2994 TEST_F(Parser, EmptyName) { |
|
2995 - EXPECT_CALL(mock_handler, RegisterRule("reg", _)) |
|
2996 + EXPECT_CALL(mock_handler, RegisterRule(ToUniqueString("reg"), _)) |
|
2997 .Times(AtMost(1)) |
|
2998 .WillRepeatedly(Return()); |
|
2999 EXPECT_FALSE(parser.Parse("reg: expr1 : expr2")); |
|
3000 } |
|
3001 |
|
3002 TEST_F(Parser, RuleLoneColon) { |
|
3003 - EXPECT_CALL(mock_handler, RegisterRule("r1", "expr")) |
|
3004 + EXPECT_CALL(mock_handler, RegisterRule(ToUniqueString("r1"), "expr")) |
|
3005 .Times(AtMost(1)) |
|
3006 .WillRepeatedly(Return()); |
|
3007 EXPECT_FALSE(parser.Parse(" r1: expr :")); |
|
3008 } |
|
3009 |
|
3010 TEST_F(Parser, RegNoExprRule) { |
|
3011 - EXPECT_CALL(mock_handler, RegisterRule("r1", "expr")) |
|
3012 + EXPECT_CALL(mock_handler, RegisterRule(ToUniqueString("r1"), "expr")) |
|
3013 .Times(AtMost(1)) |
|
3014 .WillRepeatedly(Return()); |
|
3015 EXPECT_FALSE(parser.Parse("r0: r1: expr")); |
|
3016 } |
|
3017 |
|
3018 class ParseHandlerFixture: public CFIFixture { |
|
3019 public: |
|
3020 ParseHandlerFixture() : CFIFixture(), handler(&cfi) { } |
|
3021 CFIFrameInfoParseHandler handler; |
|
3022 }; |
|
3023 |
|
3024 class ParseHandler: public ParseHandlerFixture, public Test { }; |
|
3025 |
|
3026 TEST_F(ParseHandler, CFARARule) { |
|
3027 handler.CFARule("reg-for-cfa"); |
|
3028 handler.RARule("reg-for-ra"); |
|
3029 - registers["reg-for-cfa"] = 0x268a9a4a3821a797ULL; |
|
3030 - registers["reg-for-ra"] = 0x6301b475b8b91c02ULL; |
|
3031 + registers[ToUniqueString("reg-for-cfa")] = 0x268a9a4a3821a797ULL; |
|
3032 + registers[ToUniqueString("reg-for-ra")] = 0x6301b475b8b91c02ULL; |
|
3033 ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
3034 &caller_registers)); |
|
3035 - ASSERT_EQ(0x268a9a4a3821a797ULL, caller_registers[".cfa"]); |
|
3036 - ASSERT_EQ(0x6301b475b8b91c02ULL, caller_registers[".ra"]); |
|
3037 + ASSERT_EQ(0x268a9a4a3821a797ULL, caller_registers[ustr__ZDcfa()]); |
|
3038 + ASSERT_EQ(0x6301b475b8b91c02ULL, caller_registers[ustr__ZDra()]); |
|
3039 } |
|
3040 |
|
3041 TEST_F(ParseHandler, RegisterRules) { |
|
3042 handler.CFARule("reg-for-cfa"); |
|
3043 handler.RARule("reg-for-ra"); |
|
3044 - handler.RegisterRule("reg1", "reg-for-reg1"); |
|
3045 - handler.RegisterRule("reg2", "reg-for-reg2"); |
|
3046 - registers["reg-for-cfa"] = 0x268a9a4a3821a797ULL; |
|
3047 - registers["reg-for-ra"] = 0x6301b475b8b91c02ULL; |
|
3048 - registers["reg-for-reg1"] = 0x06cde8e2ff062481ULL; |
|
3049 - registers["reg-for-reg2"] = 0xff0c4f76403173e2ULL; |
|
3050 + handler.RegisterRule(ToUniqueString("reg1"), "reg-for-reg1"); |
|
3051 + handler.RegisterRule(ToUniqueString("reg2"), "reg-for-reg2"); |
|
3052 + registers[ToUniqueString("reg-for-cfa")] = 0x268a9a4a3821a797ULL; |
|
3053 + registers[ToUniqueString("reg-for-ra")] = 0x6301b475b8b91c02ULL; |
|
3054 + registers[ToUniqueString("reg-for-reg1")] = 0x06cde8e2ff062481ULL; |
|
3055 + registers[ToUniqueString("reg-for-reg2")] = 0xff0c4f76403173e2ULL; |
|
3056 ASSERT_TRUE(cfi.FindCallerRegs<uint64_t>(registers, memory, |
|
3057 &caller_registers)); |
|
3058 - ASSERT_EQ(0x268a9a4a3821a797ULL, caller_registers[".cfa"]); |
|
3059 - ASSERT_EQ(0x6301b475b8b91c02ULL, caller_registers[".ra"]); |
|
3060 - ASSERT_EQ(0x06cde8e2ff062481ULL, caller_registers["reg1"]); |
|
3061 - ASSERT_EQ(0xff0c4f76403173e2ULL, caller_registers["reg2"]); |
|
3062 + ASSERT_EQ(0x268a9a4a3821a797ULL, caller_registers[ustr__ZDcfa()]); |
|
3063 + ASSERT_EQ(0x6301b475b8b91c02ULL, caller_registers[ustr__ZDra()]); |
|
3064 + ASSERT_EQ(0x06cde8e2ff062481ULL, caller_registers[ToUniqueString("reg1")]); |
|
3065 + ASSERT_EQ(0xff0c4f76403173e2ULL, caller_registers[ToUniqueString("reg2")]); |
|
3066 } |
|
3067 |
|
3068 struct SimpleCFIWalkerFixture { |
|
3069 struct RawContext { |
|
3070 uint64_t r0, r1, r2, r3, r4, sp, pc; |
|
3071 }; |
|
3072 enum Validity { |
|
3073 R0_VALID = 0x01, |
|
3074 @@ -475,23 +493,23 @@ |
|
3075 CFIFrameInfo call_frame_info; |
|
3076 CFIWalker walker; |
|
3077 MockMemoryRegion memory; |
|
3078 RawContext callee_context, caller_context; |
|
3079 }; |
|
3080 |
|
3081 SimpleCFIWalkerFixture::CFIWalker::RegisterSet |
|
3082 SimpleCFIWalkerFixture::register_map[7] = { |
|
3083 - { "r0", NULL, true, R0_VALID, &RawContext::r0 }, |
|
3084 - { "r1", NULL, true, R1_VALID, &RawContext::r1 }, |
|
3085 - { "r2", NULL, false, R2_VALID, &RawContext::r2 }, |
|
3086 - { "r3", NULL, false, R3_VALID, &RawContext::r3 }, |
|
3087 - { "r4", NULL, true, R4_VALID, &RawContext::r4 }, |
|
3088 - { "sp", ".cfa", true, SP_VALID, &RawContext::sp }, |
|
3089 - { "pc", ".ra", true, PC_VALID, &RawContext::pc }, |
|
3090 + { ToUniqueString("r0"), NULL, true, R0_VALID, &RawContext::r0 }, |
|
3091 + { ToUniqueString("r1"), NULL, true, R1_VALID, &RawContext::r1 }, |
|
3092 + { ToUniqueString("r2"), NULL, false, R2_VALID, &RawContext::r2 }, |
|
3093 + { ToUniqueString("r3"), NULL, false, R3_VALID, &RawContext::r3 }, |
|
3094 + { ToUniqueString("r4"), NULL, true, R4_VALID, &RawContext::r4 }, |
|
3095 + { ToUniqueString("sp"), ustr__ZDcfa(), true, SP_VALID, &RawContext::sp }, |
|
3096 + { ToUniqueString("pc"), ustr__ZDra(), true, PC_VALID, &RawContext::pc }, |
|
3097 }; |
|
3098 |
|
3099 class SimpleWalker: public SimpleCFIWalkerFixture, public Test { }; |
|
3100 |
|
3101 TEST_F(SimpleWalker, Walk) { |
|
3102 // Stack_top is the current stack pointer, pointing to the lowest |
|
3103 // address of a frame that looks like this (all 64-bit words): |
|
3104 // |
|
3105 @@ -516,18 +534,20 @@ |
|
3106 // Saved return address. |
|
3107 EXPECT_CALL(memory, |
|
3108 GetMemoryAtAddress(stack_top + 16, A<uint64_t *>())) |
|
3109 .WillRepeatedly(DoAll(SetArgumentPointee<1>(0xba5ad6d9acce28deULL), |
|
3110 Return(true))); |
|
3111 |
|
3112 call_frame_info.SetCFARule(Module::Expr("sp 24 +")); |
|
3113 call_frame_info.SetRARule(Module::Expr(".cfa 8 - ^")); |
|
3114 - call_frame_info.SetRegisterRule("r0", Module::Expr(".cfa 24 - ^")); |
|
3115 - call_frame_info.SetRegisterRule("r1", Module::Expr("r2")); |
|
3116 + call_frame_info.SetRegisterRule(ToUniqueString("r0"), |
|
3117 + Module::Expr(".cfa 24 - ^")); |
|
3118 + call_frame_info.SetRegisterRule(ToUniqueString("r1"), |
|
3119 + Module::Expr("r2")); |
|
3120 |
|
3121 callee_context.r0 = 0x94e030ca79edd119ULL; |
|
3122 callee_context.r1 = 0x937b4d7e95ce52d9ULL; |
|
3123 callee_context.r2 = 0x5fe0027416b8b62aULL; // caller's r1 |
|
3124 // callee_context.r3 is not valid in callee. |
|
3125 // callee_context.r4 is not valid in callee. |
|
3126 callee_context.sp = stack_top; |
|
3127 callee_context.pc = 0x25b21b224311d280ULL; |
|
3128 diff --git a/src/processor/fast_source_line_resolver_unittest.cc b/src/processor/fast_source_line_resolver_unittest.cc |
|
3129 --- a/src/processor/fast_source_line_resolver_unittest.cc |
|
3130 +++ b/src/processor/fast_source_line_resolver_unittest.cc |
|
3131 @@ -51,25 +51,34 @@ |
|
3132 #include "processor/module_serializer.h" |
|
3133 #include "processor/module_comparer.h" |
|
3134 |
|
3135 namespace { |
|
3136 |
|
3137 using google_breakpad::SourceLineResolverBase; |
|
3138 using google_breakpad::BasicSourceLineResolver; |
|
3139 using google_breakpad::FastSourceLineResolver; |
|
3140 +using google_breakpad::FromUniqueString; |
|
3141 using google_breakpad::ModuleSerializer; |
|
3142 using google_breakpad::ModuleComparer; |
|
3143 using google_breakpad::CFIFrameInfo; |
|
3144 using google_breakpad::CodeModule; |
|
3145 using google_breakpad::MemoryRegion; |
|
3146 using google_breakpad::StackFrame; |
|
3147 +using google_breakpad::ToUniqueString; |
|
3148 using google_breakpad::WindowsFrameInfo; |
|
3149 using google_breakpad::linked_ptr; |
|
3150 using google_breakpad::scoped_ptr; |
|
3151 +using google_breakpad::ustr__ZDcfa; |
|
3152 +using google_breakpad::ustr__ZDra; |
|
3153 +using google_breakpad::ustr__ZSebx; |
|
3154 +using google_breakpad::ustr__ZSebp; |
|
3155 +using google_breakpad::ustr__ZSedi; |
|
3156 +using google_breakpad::ustr__ZSesi; |
|
3157 +using google_breakpad::ustr__ZSesp; |
|
3158 |
|
3159 class TestCodeModule : public CodeModule { |
|
3160 public: |
|
3161 explicit TestCodeModule(string code_file) : code_file_(code_file) {} |
|
3162 virtual ~TestCodeModule() {} |
|
3163 |
|
3164 virtual uint64_t base_address() const { return 0; } |
|
3165 virtual uint64_t size() const { return 0xb000; } |
|
3166 @@ -119,34 +128,34 @@ |
|
3167 // association. (That is, ACTUAL's associations should be a subset of |
|
3168 // EXPECTED's.) Also verify that ACTUAL has associations for ".ra" and |
|
3169 // ".cfa". |
|
3170 static bool VerifyRegisters( |
|
3171 const char *file, int line, |
|
3172 const CFIFrameInfo::RegisterValueMap<uint32_t> &expected, |
|
3173 const CFIFrameInfo::RegisterValueMap<uint32_t> &actual) { |
|
3174 CFIFrameInfo::RegisterValueMap<uint32_t>::const_iterator a; |
|
3175 - a = actual.find(".cfa"); |
|
3176 + a = actual.find(ustr__ZDcfa()); |
|
3177 if (a == actual.end()) |
|
3178 return false; |
|
3179 - a = actual.find(".ra"); |
|
3180 + a = actual.find(ustr__ZDra()); |
|
3181 if (a == actual.end()) |
|
3182 return false; |
|
3183 for (a = actual.begin(); a != actual.end(); a++) { |
|
3184 CFIFrameInfo::RegisterValueMap<uint32_t>::const_iterator e = |
|
3185 expected.find(a->first); |
|
3186 if (e == expected.end()) { |
|
3187 fprintf(stderr, "%s:%d: unexpected register '%s' recovered, value 0x%x\n", |
|
3188 - file, line, a->first.c_str(), a->second); |
|
3189 + file, line, FromUniqueString(a->first), a->second); |
|
3190 return false; |
|
3191 } |
|
3192 if (e->second != a->second) { |
|
3193 fprintf(stderr, |
|
3194 "%s:%d: register '%s' recovered value was 0x%x, expected 0x%x\n", |
|
3195 - file, line, a->first.c_str(), a->second, e->second); |
|
3196 + file, line, FromUniqueString(a->first), a->second, e->second); |
|
3197 return false; |
|
3198 } |
|
3199 // Don't complain if this doesn't recover all registers. Although |
|
3200 // the DWARF spec says that unmentioned registers are undefined, |
|
3201 // GCC uses omission to mean that they are unchanged. |
|
3202 } |
|
3203 return true; |
|
3204 } |
|
3205 @@ -282,81 +291,81 @@ |
|
3206 |
|
3207 CFIFrameInfo::RegisterValueMap<uint32_t> current_registers; |
|
3208 CFIFrameInfo::RegisterValueMap<uint32_t> caller_registers; |
|
3209 CFIFrameInfo::RegisterValueMap<uint32_t> expected_caller_registers; |
|
3210 MockMemoryRegion memory; |
|
3211 |
|
3212 // Regardless of which instruction evaluation takes place at, it |
|
3213 // should produce the same values for the caller's registers. |
|
3214 - expected_caller_registers[".cfa"] = 0x1001c; |
|
3215 - expected_caller_registers[".ra"] = 0xf6438648; |
|
3216 - expected_caller_registers["$ebp"] = 0x10038; |
|
3217 - expected_caller_registers["$ebx"] = 0x98ecadc3; |
|
3218 - expected_caller_registers["$esi"] = 0x878f7524; |
|
3219 - expected_caller_registers["$edi"] = 0x6312f9a5; |
|
3220 + expected_caller_registers[ustr__ZDcfa()] = 0x1001c; |
|
3221 + expected_caller_registers[ustr__ZDra()] = 0xf6438648; |
|
3222 + expected_caller_registers[ustr__ZSebp()] = 0x10038; |
|
3223 + expected_caller_registers[ustr__ZSebx()] = 0x98ecadc3; |
|
3224 + expected_caller_registers[ustr__ZSesi()] = 0x878f7524; |
|
3225 + expected_caller_registers[ustr__ZSedi()] = 0x6312f9a5; |
|
3226 |
|
3227 frame.instruction = 0x3d40; |
|
3228 frame.module = &module1; |
|
3229 current_registers.clear(); |
|
3230 - current_registers["$esp"] = 0x10018; |
|
3231 - current_registers["$ebp"] = 0x10038; |
|
3232 - current_registers["$ebx"] = 0x98ecadc3; |
|
3233 - current_registers["$esi"] = 0x878f7524; |
|
3234 - current_registers["$edi"] = 0x6312f9a5; |
|
3235 + current_registers[ustr__ZSesp()] = 0x10018; |
|
3236 + current_registers[ustr__ZSebp()] = 0x10038; |
|
3237 + current_registers[ustr__ZSebx()] = 0x98ecadc3; |
|
3238 + current_registers[ustr__ZSesi()] = 0x878f7524; |
|
3239 + current_registers[ustr__ZSedi()] = 0x6312f9a5; |
|
3240 cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); |
|
3241 ASSERT_TRUE(cfi_frame_info.get()); |
|
3242 ASSERT_TRUE(cfi_frame_info.get() |
|
3243 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
3244 &caller_registers)); |
|
3245 ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__, |
|
3246 expected_caller_registers, caller_registers)); |
|
3247 |
|
3248 frame.instruction = 0x3d41; |
|
3249 - current_registers["$esp"] = 0x10014; |
|
3250 + current_registers[ustr__ZSesp()] = 0x10014; |
|
3251 cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); |
|
3252 ASSERT_TRUE(cfi_frame_info.get()); |
|
3253 ASSERT_TRUE(cfi_frame_info.get() |
|
3254 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
3255 &caller_registers)); |
|
3256 ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__, |
|
3257 expected_caller_registers, caller_registers)); |
|
3258 |
|
3259 frame.instruction = 0x3d43; |
|
3260 - current_registers["$ebp"] = 0x10014; |
|
3261 + current_registers[ustr__ZSebp()] = 0x10014; |
|
3262 cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); |
|
3263 ASSERT_TRUE(cfi_frame_info.get()); |
|
3264 ASSERT_TRUE(cfi_frame_info.get() |
|
3265 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
3266 &caller_registers)); |
|
3267 VerifyRegisters(__FILE__, __LINE__, |
|
3268 expected_caller_registers, caller_registers); |
|
3269 |
|
3270 frame.instruction = 0x3d54; |
|
3271 - current_registers["$ebx"] = 0x6864f054U; |
|
3272 + current_registers[ustr__ZSebx()] = 0x6864f054U; |
|
3273 cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); |
|
3274 ASSERT_TRUE(cfi_frame_info.get()); |
|
3275 ASSERT_TRUE(cfi_frame_info.get() |
|
3276 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
3277 &caller_registers)); |
|
3278 VerifyRegisters(__FILE__, __LINE__, |
|
3279 expected_caller_registers, caller_registers); |
|
3280 |
|
3281 frame.instruction = 0x3d5a; |
|
3282 - current_registers["$esi"] = 0x6285f79aU; |
|
3283 + current_registers[ustr__ZSesi()] = 0x6285f79aU; |
|
3284 cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); |
|
3285 ASSERT_TRUE(cfi_frame_info.get()); |
|
3286 ASSERT_TRUE(cfi_frame_info.get() |
|
3287 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
3288 &caller_registers)); |
|
3289 VerifyRegisters(__FILE__, __LINE__, |
|
3290 expected_caller_registers, caller_registers); |
|
3291 |
|
3292 frame.instruction = 0x3d84; |
|
3293 - current_registers["$edi"] = 0x64061449U; |
|
3294 + current_registers[ustr__ZSedi()] = 0x64061449U; |
|
3295 cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame)); |
|
3296 ASSERT_TRUE(cfi_frame_info.get()); |
|
3297 ASSERT_TRUE(cfi_frame_info.get() |
|
3298 ->FindCallerRegs<uint32_t>(current_registers, memory, |
|
3299 &caller_registers)); |
|
3300 VerifyRegisters(__FILE__, __LINE__, |
|
3301 expected_caller_registers, caller_registers); |
|
3302 |
|
3303 diff --git a/src/processor/postfix_evaluator-inl.h b/src/processor/postfix_evaluator-inl.h |
|
3304 --- a/src/processor/postfix_evaluator-inl.h |
|
3305 +++ b/src/processor/postfix_evaluator-inl.h |
|
3306 @@ -51,23 +51,25 @@ |
|
3307 namespace google_breakpad { |
|
3308 |
|
3309 using std::istringstream; |
|
3310 using std::ostringstream; |
|
3311 |
|
3312 |
|
3313 // A small class used in Evaluate to make sure to clean up the stack |
|
3314 // before returning failure. |
|
3315 +template<typename ValueType> |
|
3316 class AutoStackClearer { |
|
3317 public: |
|
3318 - explicit AutoStackClearer(vector<string> *stack) : stack_(stack) {} |
|
3319 + explicit AutoStackClearer(vector<StackElem<ValueType> > *stack) |
|
3320 + : stack_(stack) {} |
|
3321 ~AutoStackClearer() { stack_->clear(); } |
|
3322 |
|
3323 private: |
|
3324 - vector<string> *stack_; |
|
3325 + vector<StackElem<ValueType> > *stack_; |
|
3326 }; |
|
3327 |
|
3328 |
|
3329 template<typename ValueType> |
|
3330 bool PostfixEvaluator<ValueType>::EvaluateToken( |
|
3331 const string &token, |
|
3332 const string &expression, |
|
3333 DictionaryValidityType *assigned) { |
|
3334 @@ -170,38 +172,57 @@ |
|
3335 BPLOG(INFO) << "Could not PopValue to get value to assign: " << |
|
3336 expression; |
|
3337 return false; |
|
3338 } |
|
3339 |
|
3340 // Assignment is only meaningful when assigning into an identifier. |
|
3341 // The identifier must name a variable, not a constant. Variables |
|
3342 // begin with '$'. |
|
3343 - string identifier; |
|
3344 + const UniqueString* identifier; |
|
3345 if (PopValueOrIdentifier(NULL, &identifier) != POP_RESULT_IDENTIFIER) { |
|
3346 BPLOG(ERROR) << "PopValueOrIdentifier returned a value, but an " |
|
3347 "identifier is needed to assign " << |
|
3348 HexString(value) << ": " << expression; |
|
3349 return false; |
|
3350 } |
|
3351 - if (identifier.empty() || identifier[0] != '$') { |
|
3352 + if (identifier == ustr__empty() || Index(identifier,0) != '$') { |
|
3353 BPLOG(ERROR) << "Can't assign " << HexString(value) << " to " << |
|
3354 identifier << ": " << expression; |
|
3355 return false; |
|
3356 } |
|
3357 |
|
3358 (*dictionary_)[identifier] = value; |
|
3359 if (assigned) |
|
3360 (*assigned)[identifier] = true; |
|
3361 } else { |
|
3362 - // The token is not an operator, it's a literal value or an identifier. |
|
3363 - // Push it onto the stack as-is. Use push_back instead of PushValue |
|
3364 - // because PushValue pushes ValueType as a string, but token is already |
|
3365 - // a string. |
|
3366 - stack_.push_back(token); |
|
3367 + // Push it onto the stack as-is, but first convert it either to a |
|
3368 + // ValueType (if a literal) or to a UniqueString* (if an identifier). |
|
3369 + // |
|
3370 + // First, try to treat the value as a literal. Literals may have leading |
|
3371 + // '-' sign, and the entire remaining string must be parseable as |
|
3372 + // ValueType. If this isn't possible, it can't be a literal, so treat it |
|
3373 + // as an identifier instead. |
|
3374 + // |
|
3375 + // Some versions of the libstdc++, the GNU standard C++ library, have |
|
3376 + // stream extractors for unsigned integer values that permit a leading |
|
3377 + // '-' sign (6.0.13); others do not (6.0.9). Since we require it, we |
|
3378 + // handle it explicitly here. |
|
3379 + istringstream token_stream(token); |
|
3380 + ValueType literal = ValueType(); |
|
3381 + bool negative = false; |
|
3382 + if (token_stream.peek() == '-') { |
|
3383 + negative = true; |
|
3384 + token_stream.get(); |
|
3385 + } |
|
3386 + if (token_stream >> literal && token_stream.peek() == EOF) { |
|
3387 + PushValue(negative ? (-literal) : literal); |
|
3388 + } else { |
|
3389 + PushIdentifier(ToUniqueString(token)); |
|
3390 + } |
|
3391 } |
|
3392 return true; |
|
3393 } |
|
3394 |
|
3395 template<typename ValueType> |
|
3396 bool PostfixEvaluator<ValueType>::EvaluateInternal( |
|
3397 const string &expression, |
|
3398 DictionaryValidityType *assigned) { |
|
3399 @@ -236,17 +257,17 @@ |
|
3400 // The expression is being exevaluated only for its side effects. Skip |
|
3401 // expressions that denote values only. |
|
3402 if (expr.how_ != Module::kExprPostfix) { |
|
3403 BPLOG(ERROR) << "Can't evaluate for side-effects: " << expr; |
|
3404 return false; |
|
3405 } |
|
3406 |
|
3407 // Ensure that the stack is cleared before returning. |
|
3408 - AutoStackClearer clearer(&stack_); |
|
3409 + AutoStackClearer<ValueType> clearer(&stack_); |
|
3410 |
|
3411 if (!EvaluateInternal(expr.postfix_, assigned)) |
|
3412 return false; |
|
3413 |
|
3414 // If there's anything left on the stack, it indicates incomplete execution. |
|
3415 // This is a failure case. If the stack is empty, evalution was complete |
|
3416 // and successful. |
|
3417 if (stack_.empty()) |
|
3418 @@ -260,17 +281,17 @@ |
|
3419 bool PostfixEvaluator<ValueType>::EvaluateForValue(const Module::Expr& expr, |
|
3420 ValueType* result) { |
|
3421 switch (expr.how_) { |
|
3422 |
|
3423 // Postfix expression. Give to the evaluator and return the |
|
3424 // one-and-only stack element that should be left over. |
|
3425 case Module::kExprPostfix: { |
|
3426 // Ensure that the stack is cleared before returning. |
|
3427 - AutoStackClearer clearer(&stack_); |
|
3428 + AutoStackClearer<ValueType> clearer(&stack_); |
|
3429 |
|
3430 if (!EvaluateInternal(expr.postfix_, NULL)) |
|
3431 return false; |
|
3432 |
|
3433 // A successful execution should leave exactly one value on the stack. |
|
3434 if (stack_.size() != 1) { |
|
3435 BPLOG(ERROR) << "Expression yielded bad number of results: " |
|
3436 << "'" << expr << "'"; |
|
3437 @@ -314,77 +335,56 @@ |
|
3438 return false; |
|
3439 } |
|
3440 } |
|
3441 |
|
3442 |
|
3443 template<typename ValueType> |
|
3444 typename PostfixEvaluator<ValueType>::PopResult |
|
3445 PostfixEvaluator<ValueType>::PopValueOrIdentifier( |
|
3446 - ValueType *value, string *identifier) { |
|
3447 + ValueType *value, const UniqueString** identifier) { |
|
3448 // There needs to be at least one element on the stack to pop. |
|
3449 if (!stack_.size()) |
|
3450 return POP_RESULT_FAIL; |
|
3451 |
|
3452 - string token = stack_.back(); |
|
3453 + StackElem<ValueType> el = stack_.back(); |
|
3454 stack_.pop_back(); |
|
3455 |
|
3456 - // First, try to treat the value as a literal. Literals may have leading |
|
3457 - // '-' sign, and the entire remaining string must be parseable as |
|
3458 - // ValueType. If this isn't possible, it can't be a literal, so treat it |
|
3459 - // as an identifier instead. |
|
3460 - // |
|
3461 - // Some versions of the libstdc++, the GNU standard C++ library, have |
|
3462 - // stream extractors for unsigned integer values that permit a leading |
|
3463 - // '-' sign (6.0.13); others do not (6.0.9). Since we require it, we |
|
3464 - // handle it explicitly here. |
|
3465 - istringstream token_stream(token); |
|
3466 - ValueType literal = ValueType(); |
|
3467 - bool negative; |
|
3468 - if (token_stream.peek() == '-') { |
|
3469 - negative = true; |
|
3470 - token_stream.get(); |
|
3471 - } else { |
|
3472 - negative = false; |
|
3473 - } |
|
3474 - if (token_stream >> literal && token_stream.peek() == EOF) { |
|
3475 - if (value) { |
|
3476 - *value = literal; |
|
3477 - } |
|
3478 - if (negative) |
|
3479 - *value = -*value; |
|
3480 + if (el.isValue) { |
|
3481 + if (value) |
|
3482 + *value = el.u.val; |
|
3483 return POP_RESULT_VALUE; |
|
3484 } else { |
|
3485 - if (identifier) { |
|
3486 - *identifier = token; |
|
3487 - } |
|
3488 + if (identifier) |
|
3489 + *identifier = el.u.ustr; |
|
3490 return POP_RESULT_IDENTIFIER; |
|
3491 } |
|
3492 } |
|
3493 |
|
3494 |
|
3495 template<typename ValueType> |
|
3496 bool PostfixEvaluator<ValueType>::PopValue(ValueType *value) { |
|
3497 ValueType literal = ValueType(); |
|
3498 - string token; |
|
3499 + const UniqueString* token; |
|
3500 PopResult result; |
|
3501 if ((result = PopValueOrIdentifier(&literal, &token)) == POP_RESULT_FAIL) { |
|
3502 return false; |
|
3503 } else if (result == POP_RESULT_VALUE) { |
|
3504 // This is the easy case. |
|
3505 *value = literal; |
|
3506 } else { // result == POP_RESULT_IDENTIFIER |
|
3507 // There was an identifier at the top of the stack. Resolve it to a |
|
3508 // value by looking it up in the dictionary. |
|
3509 typename DictionaryType::const_iterator iterator = |
|
3510 dictionary_->find(token); |
|
3511 if (iterator == dictionary_->end()) { |
|
3512 // The identifier wasn't found in the dictionary. Don't imply any |
|
3513 // default value, just fail. |
|
3514 - BPLOG(INFO) << "Identifier " << token << " not in dictionary"; |
|
3515 + BPLOG(INFO) << "Identifier " << FromUniqueString(token) |
|
3516 + << " not in dictionary"; |
|
3517 return false; |
|
3518 } |
|
3519 |
|
3520 *value = iterator->second; |
|
3521 } |
|
3522 |
|
3523 return true; |
|
3524 } |
|
3525 @@ -394,18 +394,23 @@ |
|
3526 bool PostfixEvaluator<ValueType>::PopValues(ValueType *value1, |
|
3527 ValueType *value2) { |
|
3528 return PopValue(value2) && PopValue(value1); |
|
3529 } |
|
3530 |
|
3531 |
|
3532 template<typename ValueType> |
|
3533 void PostfixEvaluator<ValueType>::PushValue(const ValueType &value) { |
|
3534 - ostringstream token_stream; |
|
3535 - token_stream << value; |
|
3536 - stack_.push_back(token_stream.str()); |
|
3537 + StackElem<ValueType> el(value); |
|
3538 + stack_.push_back(el); |
|
3539 +} |
|
3540 + |
|
3541 +template<typename ValueType> |
|
3542 +void PostfixEvaluator<ValueType>::PushIdentifier(const UniqueString* str) { |
|
3543 + StackElem<ValueType> el(str); |
|
3544 + stack_.push_back(el); |
|
3545 } |
|
3546 |
|
3547 |
|
3548 } // namespace google_breakpad |
|
3549 |
|
3550 |
|
3551 #endif // PROCESSOR_POSTFIX_EVALUATOR_INL_H__ |
|
3552 diff --git a/src/processor/postfix_evaluator.h b/src/processor/postfix_evaluator.h |
|
3553 --- a/src/processor/postfix_evaluator.h |
|
3554 +++ b/src/processor/postfix_evaluator.h |
|
3555 @@ -70,30 +70,41 @@ |
|
3556 #define PROCESSOR_POSTFIX_EVALUATOR_H__ |
|
3557 |
|
3558 |
|
3559 #include <map> |
|
3560 #include <string> |
|
3561 #include <vector> |
|
3562 |
|
3563 #include "common/using_std_string.h" |
|
3564 +#include "common/unique_string.h" |
|
3565 #include "common/module.h" |
|
3566 |
|
3567 namespace google_breakpad { |
|
3568 |
|
3569 using std::map; |
|
3570 using std::vector; |
|
3571 |
|
3572 class MemoryRegion; |
|
3573 |
|
3574 +// A union type for elements in the postfix evaluator's stack. |
|
3575 +template<typename ValueType> |
|
3576 +class StackElem { |
|
3577 + public: |
|
3578 + StackElem(ValueType val) { isValue = true; u.val = val; } |
|
3579 + StackElem(const UniqueString* ustr) { isValue = false; u.ustr = ustr; } |
|
3580 + bool isValue; |
|
3581 + union { ValueType val; const UniqueString* ustr; } u; |
|
3582 +}; |
|
3583 + |
|
3584 template<typename ValueType> |
|
3585 class PostfixEvaluator { |
|
3586 public: |
|
3587 - typedef map<string, ValueType> DictionaryType; |
|
3588 - typedef map<string, bool> DictionaryValidityType; |
|
3589 + typedef map<const UniqueString*, ValueType> DictionaryType; |
|
3590 + typedef map<const UniqueString*, bool> DictionaryValidityType; |
|
3591 |
|
3592 // Create a PostfixEvaluator object that may be used (with Evaluate) on |
|
3593 // one or more expressions. PostfixEvaluator does not take ownership of |
|
3594 // either argument. |memory| may be NULL, in which case dereferencing |
|
3595 // (^) will not be supported. |dictionary| may be NULL, but evaluation |
|
3596 // will fail in that case unless set_dictionary is used before calling |
|
3597 // Evaluate. |
|
3598 PostfixEvaluator(DictionaryType *dictionary, const MemoryRegion *memory) |
|
3599 @@ -128,24 +139,28 @@ |
|
3600 }; |
|
3601 |
|
3602 // Retrieves the topmost literal value, constant, or variable from the |
|
3603 // stack. Returns POP_RESULT_VALUE if the topmost entry is a literal |
|
3604 // value, and sets |value| accordingly. Returns POP_RESULT_IDENTIFIER |
|
3605 // if the topmost entry is a constant or variable identifier, and sets |
|
3606 // |identifier| accordingly. Returns POP_RESULT_FAIL on failure, such |
|
3607 // as when the stack is empty. |
|
3608 - PopResult PopValueOrIdentifier(ValueType *value, string *identifier); |
|
3609 + PopResult PopValueOrIdentifier(ValueType *value, |
|
3610 + const UniqueString** identifier); |
|
3611 |
|
3612 // Retrieves the topmost value on the stack. If the topmost entry is |
|
3613 // an identifier, the dictionary is queried for the identifier's value. |
|
3614 // Returns false on failure, such as when the stack is empty or when |
|
3615 // a nonexistent identifier is named. |
|
3616 bool PopValue(ValueType *value); |
|
3617 |
|
3618 + // Pushes a UniqueString* on the stack. |
|
3619 + void PushIdentifier(const UniqueString* ustr); |
|
3620 + |
|
3621 // Retrieves the top two values on the stack, in the style of PopValue. |
|
3622 // value2 is popped before value1, so that value1 corresponds to the |
|
3623 // entry that was pushed prior to value2. Returns false on failure. |
|
3624 bool PopValues(ValueType *value1, ValueType *value2); |
|
3625 |
|
3626 // Pushes a new value onto the stack. |
|
3627 void PushValue(const ValueType &value); |
|
3628 |
|
3629 @@ -166,15 +181,15 @@ |
|
3630 |
|
3631 // If non-NULL, the MemoryRegion used for dereference (^) operations. |
|
3632 // If NULL, dereferencing is unsupported and will fail. Weak pointer. |
|
3633 const MemoryRegion *memory_; |
|
3634 |
|
3635 // The stack contains state information as execution progresses. Values |
|
3636 // are pushed on to it as the expression string is read and as operations |
|
3637 // yield values; values are popped when used as operands to operators. |
|
3638 - vector<string> stack_; |
|
3639 + vector<StackElem<ValueType> > stack_; |
|
3640 }; |
|
3641 |
|
3642 } // namespace google_breakpad |
|
3643 |
|
3644 |
|
3645 #endif // PROCESSOR_POSTFIX_EVALUATOR_H__ |
|
3646 diff --git a/src/processor/postfix_evaluator_unittest.cc b/src/processor/postfix_evaluator_unittest.cc |
|
3647 --- a/src/processor/postfix_evaluator_unittest.cc |
|
3648 +++ b/src/processor/postfix_evaluator_unittest.cc |
|
3649 @@ -43,18 +43,32 @@ |
|
3650 #include "google_breakpad/processor/memory_region.h" |
|
3651 #include "processor/logging.h" |
|
3652 |
|
3653 |
|
3654 namespace { |
|
3655 |
|
3656 |
|
3657 using std::map; |
|
3658 +using google_breakpad::FromUniqueString; |
|
3659 using google_breakpad::MemoryRegion; |
|
3660 using google_breakpad::PostfixEvaluator; |
|
3661 +using google_breakpad::ToUniqueString; |
|
3662 +using google_breakpad::UniqueString; |
|
3663 +using google_breakpad::ustr__ZDcbParams; |
|
3664 +using google_breakpad::ustr__ZDcbSavedRegs; |
|
3665 +using google_breakpad::ustr__ZDcfa; |
|
3666 +using google_breakpad::ustr__ZDra; |
|
3667 +using google_breakpad::ustr__ZDraSearchStart; |
|
3668 +using google_breakpad::ustr__ZSebx; |
|
3669 +using google_breakpad::ustr__ZSebp; |
|
3670 +using google_breakpad::ustr__ZSedi; |
|
3671 +using google_breakpad::ustr__ZSeip; |
|
3672 +using google_breakpad::ustr__ZSesi; |
|
3673 +using google_breakpad::ustr__ZSesp; |
|
3674 |
|
3675 |
|
3676 // FakeMemoryRegion is used to test PostfixEvaluator's dereference (^) |
|
3677 // operator. The result of dereferencing a value is one greater than |
|
3678 // the value. |
|
3679 class FakeMemoryRegion : public MemoryRegion { |
|
3680 public: |
|
3681 virtual uint64_t GetBase() const { return 0; } |
|
3682 @@ -95,17 +109,17 @@ |
|
3683 // The list of tests. |
|
3684 const EvaluateTest *evaluate_tests; |
|
3685 |
|
3686 // The number of tests. |
|
3687 unsigned int evaluate_test_count; |
|
3688 |
|
3689 // Identifiers and their expected values upon completion of the Evaluate |
|
3690 // tests in the set. |
|
3691 - map<string, unsigned int> *validate_data; |
|
3692 + map<const UniqueString*, unsigned int> *validate_data; |
|
3693 }; |
|
3694 |
|
3695 |
|
3696 struct EvaluateForValueTest { |
|
3697 // Expression passed to PostfixEvaluator::Evaluate. |
|
3698 const string expression; |
|
3699 |
|
3700 // True if the expression is expected to be evaluable, false if evaluation |
|
3701 @@ -147,39 +161,39 @@ |
|
3702 { "$rMul 9 6 * =", true }, // $rMul = 9 * 6 = 54 |
|
3703 { "$rSub 9 6 - =", true }, // $rSub = 9 - 6 = 3 |
|
3704 { "$rDivQ 9 6 / =", true }, // $rDivQ = 9 / 6 = 1 |
|
3705 { "$rDivM 9 6 % =", true }, // $rDivM = 9 % 6 = 3 |
|
3706 { "$rDeref 9 ^ =", true }, // $rDeref = ^9 = 10 (FakeMemoryRegion) |
|
3707 { "$rAlign 36 8 @ =", true }, // $rAlign = 36 @ 8 |
|
3708 { "$rAdd3 2 2 + =$rMul2 9 6 * =", true } // smashed-equals tokenization |
|
3709 }; |
|
3710 - map<string, unsigned int> validate_data_0; |
|
3711 - validate_data_0["$rAdd"] = 8; |
|
3712 - validate_data_0["$rAdd2"] = 4; |
|
3713 - validate_data_0["$rSub"] = 3; |
|
3714 - validate_data_0["$rMul"] = 54; |
|
3715 - validate_data_0["$rDivQ"] = 1; |
|
3716 - validate_data_0["$rDivM"] = 3; |
|
3717 - validate_data_0["$rDeref"] = 10; |
|
3718 - validate_data_0["$rAlign"] = 32; |
|
3719 - validate_data_0["$rAdd3"] = 4; |
|
3720 - validate_data_0["$rMul2"] = 54; |
|
3721 + map<const UniqueString*, unsigned int> validate_data_0; |
|
3722 + validate_data_0[ToUniqueString("$rAdd")] = 8; |
|
3723 + validate_data_0[ToUniqueString("$rAdd2")] = 4; |
|
3724 + validate_data_0[ToUniqueString("$rSub")] = 3; |
|
3725 + validate_data_0[ToUniqueString("$rMul")] = 54; |
|
3726 + validate_data_0[ToUniqueString("$rDivQ")] = 1; |
|
3727 + validate_data_0[ToUniqueString("$rDivM")] = 3; |
|
3728 + validate_data_0[ToUniqueString("$rDeref")] = 10; |
|
3729 + validate_data_0[ToUniqueString("$rAlign")] = 32; |
|
3730 + validate_data_0[ToUniqueString("$rAdd3")] = 4; |
|
3731 + validate_data_0[ToUniqueString("$rMul2")] = 54; |
|
3732 |
|
3733 // The second test set simulates a couple of MSVC program strings. |
|
3734 // The data is fudged a little bit because the tests use FakeMemoryRegion |
|
3735 // instead of a real stack snapshot, but the program strings are real and |
|
3736 // the implementation doesn't know or care that the data is not real. |
|
3737 PostfixEvaluator<unsigned int>::DictionaryType dictionary_1; |
|
3738 - dictionary_1["$ebp"] = 0xbfff0010; |
|
3739 - dictionary_1["$eip"] = 0x10000000; |
|
3740 - dictionary_1["$esp"] = 0xbfff0000; |
|
3741 - dictionary_1[".cbSavedRegs"] = 4; |
|
3742 - dictionary_1[".cbParams"] = 4; |
|
3743 - dictionary_1[".raSearchStart"] = 0xbfff0020; |
|
3744 + dictionary_1[ustr__ZSebp()] = 0xbfff0010; |
|
3745 + dictionary_1[ustr__ZSeip()] = 0x10000000; |
|
3746 + dictionary_1[ustr__ZSesp()] = 0xbfff0000; |
|
3747 + dictionary_1[ustr__ZDcbSavedRegs()] = 4; |
|
3748 + dictionary_1[ustr__ZDcbParams()] = 4; |
|
3749 + dictionary_1[ustr__ZDraSearchStart()] = 0xbfff0020; |
|
3750 const EvaluateTest evaluate_tests_1[] = { |
|
3751 { "$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = " |
|
3752 "$L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =", true }, |
|
3753 // Intermediate state: $T0 = 0xbfff0010, $eip = 0xbfff0015, |
|
3754 // $ebp = 0xbfff0011, $esp = 0xbfff0018, |
|
3755 // $L = 0xbfff000c, $P = 0xbfff001c |
|
3756 { "$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = " |
|
3757 "$L $T0 .cbSavedRegs - = $P $T0 8 + .cbParams + = $ebx $T0 28 - ^ =", |
|
3758 @@ -188,28 +202,28 @@ |
|
3759 // $ebp = 0xbfff0012, $esp = 0xbfff0019, |
|
3760 // $L = 0xbfff000d, $P = 0xbfff001d, |
|
3761 // $ebx = 0xbffefff6 |
|
3762 { "$T0 $ebp = $T2 $esp = $T1 .raSearchStart = $eip $T1 ^ = $ebp $T0 = " |
|
3763 "$esp $T1 4 + = $L $T0 .cbSavedRegs - = $P $T1 4 + .cbParams + = " |
|
3764 "$ebx $T0 28 - ^ =", |
|
3765 true } |
|
3766 }; |
|
3767 - map<string, unsigned int> validate_data_1; |
|
3768 - validate_data_1["$T0"] = 0xbfff0012; |
|
3769 - validate_data_1["$T1"] = 0xbfff0020; |
|
3770 - validate_data_1["$T2"] = 0xbfff0019; |
|
3771 - validate_data_1["$eip"] = 0xbfff0021; |
|
3772 - validate_data_1["$ebp"] = 0xbfff0012; |
|
3773 - validate_data_1["$esp"] = 0xbfff0024; |
|
3774 - validate_data_1["$L"] = 0xbfff000e; |
|
3775 - validate_data_1["$P"] = 0xbfff0028; |
|
3776 - validate_data_1["$ebx"] = 0xbffefff7; |
|
3777 - validate_data_1[".cbSavedRegs"] = 4; |
|
3778 - validate_data_1[".cbParams"] = 4; |
|
3779 + map<const UniqueString*, unsigned int> validate_data_1; |
|
3780 + validate_data_1[ToUniqueString("$T0")] = 0xbfff0012; |
|
3781 + validate_data_1[ToUniqueString("$T1")] = 0xbfff0020; |
|
3782 + validate_data_1[ToUniqueString("$T2")] = 0xbfff0019; |
|
3783 + validate_data_1[ustr__ZSeip()] = 0xbfff0021; |
|
3784 + validate_data_1[ustr__ZSebp()] = 0xbfff0012; |
|
3785 + validate_data_1[ustr__ZSesp()] = 0xbfff0024; |
|
3786 + validate_data_1[ToUniqueString("$L")] = 0xbfff000e; |
|
3787 + validate_data_1[ToUniqueString("$P")] = 0xbfff0028; |
|
3788 + validate_data_1[ustr__ZSebx()] = 0xbffefff7; |
|
3789 + validate_data_1[ustr__ZDcbSavedRegs()] = 4; |
|
3790 + validate_data_1[ustr__ZDcbParams()] = 4; |
|
3791 |
|
3792 EvaluateTestSet evaluate_test_sets[] = { |
|
3793 { &dictionary_0, evaluate_tests_0, |
|
3794 sizeof(evaluate_tests_0) / sizeof(EvaluateTest), &validate_data_0 }, |
|
3795 { &dictionary_1, evaluate_tests_1, |
|
3796 sizeof(evaluate_tests_1) / sizeof(EvaluateTest), &validate_data_1 }, |
|
3797 }; |
|
3798 |
|
3799 @@ -251,97 +265,100 @@ |
|
3800 evaluate_test->expression.c_str(), |
|
3801 evaluate_test->evaluable ? "evaluable" : "not evaluable", |
|
3802 result ? "evaluted" : "not evaluated"); |
|
3803 return false; |
|
3804 } |
|
3805 } |
|
3806 |
|
3807 // Validate the results. |
|
3808 - for (map<string, unsigned int>::const_iterator validate_iterator = |
|
3809 + for (map<const UniqueString*, unsigned int>::const_iterator |
|
3810 + validate_iterator = |
|
3811 evaluate_test_set->validate_data->begin(); |
|
3812 validate_iterator != evaluate_test_set->validate_data->end(); |
|
3813 ++validate_iterator) { |
|
3814 - const string identifier = validate_iterator->first; |
|
3815 + const UniqueString* identifier = validate_iterator->first; |
|
3816 unsigned int expected_value = validate_iterator->second; |
|
3817 |
|
3818 - map<string, unsigned int>::const_iterator dictionary_iterator = |
|
3819 + map<const UniqueString*, unsigned int>::const_iterator |
|
3820 + dictionary_iterator = |
|
3821 evaluate_test_set->dictionary->find(identifier); |
|
3822 |
|
3823 // The identifier must exist in the dictionary. |
|
3824 if (dictionary_iterator == evaluate_test_set->dictionary->end()) { |
|
3825 fprintf(stderr, "FAIL: evaluate test set %d/%d, " |
|
3826 "validate identifier \"%s\", " |
|
3827 "expected %d, observed not found\n", |
|
3828 evaluate_test_set_index, evaluate_test_set_count, |
|
3829 - identifier.c_str(), expected_value); |
|
3830 + FromUniqueString(identifier), expected_value); |
|
3831 return false; |
|
3832 } |
|
3833 |
|
3834 // The value in the dictionary must be the same as the expected value. |
|
3835 unsigned int observed_value = dictionary_iterator->second; |
|
3836 if (expected_value != observed_value) { |
|
3837 fprintf(stderr, "FAIL: evaluate test set %d/%d, " |
|
3838 "validate identifier \"%s\", " |
|
3839 "expected %d, observed %d\n", |
|
3840 evaluate_test_set_index, evaluate_test_set_count, |
|
3841 - identifier.c_str(), expected_value, observed_value); |
|
3842 + FromUniqueString(identifier), expected_value, observed_value); |
|
3843 return false; |
|
3844 } |
|
3845 |
|
3846 // The value must be set in the "assigned" dictionary if it was a |
|
3847 // variable. It must not have been assigned if it was a constant. |
|
3848 - bool expected_assigned = identifier[0] == '$'; |
|
3849 + bool expected_assigned = FromUniqueString(identifier)[0] == '$'; |
|
3850 bool observed_assigned = false; |
|
3851 PostfixEvaluator<unsigned int>::DictionaryValidityType::const_iterator |
|
3852 iterator_assigned = assigned.find(identifier); |
|
3853 if (iterator_assigned != assigned.end()) { |
|
3854 observed_assigned = iterator_assigned->second; |
|
3855 } |
|
3856 if (expected_assigned != observed_assigned) { |
|
3857 fprintf(stderr, "FAIL: evaluate test set %d/%d, " |
|
3858 "validate assignment of \"%s\", " |
|
3859 "expected %d, observed %d\n", |
|
3860 evaluate_test_set_index, evaluate_test_set_count, |
|
3861 - identifier.c_str(), expected_assigned, observed_assigned); |
|
3862 + FromUniqueString(identifier), expected_assigned, |
|
3863 + observed_assigned); |
|
3864 return false; |
|
3865 } |
|
3866 } |
|
3867 } |
|
3868 |
|
3869 // EvaluateForValue tests. |
|
3870 PostfixEvaluator<unsigned int>::DictionaryType dictionary_2; |
|
3871 - dictionary_2["$ebp"] = 0xbfff0010; |
|
3872 - dictionary_2["$eip"] = 0x10000000; |
|
3873 - dictionary_2["$esp"] = 0xbfff0000; |
|
3874 - dictionary_2[".cbSavedRegs"] = 4; |
|
3875 - dictionary_2[".cbParams"] = 4; |
|
3876 - dictionary_2[".raSearchStart"] = 0xbfff0020; |
|
3877 + dictionary_2[ustr__ZSebp()] = 0xbfff0010; |
|
3878 + dictionary_2[ustr__ZSeip()] = 0x10000000; |
|
3879 + dictionary_2[ustr__ZSesp()] = 0xbfff0000; |
|
3880 + dictionary_2[ustr__ZDcbSavedRegs()] = 4; |
|
3881 + dictionary_2[ustr__ZDcbParams()] = 4; |
|
3882 + dictionary_2[ustr__ZDraSearchStart()] = 0xbfff0020; |
|
3883 const EvaluateForValueTest evaluate_for_value_tests_2[] = { |
|
3884 { "28907223", true, 28907223 }, // simple constant |
|
3885 { "89854293 40010015 +", true, 89854293 + 40010015 }, // arithmetic |
|
3886 { "-870245 8769343 +", true, 7899098 }, // negative constants |
|
3887 { "$ebp $esp - $eip +", true, 0x10000010 }, // variable references |
|
3888 { "18929794 34015074", false, 0 }, // too many values |
|
3889 { "$ebp $ebp 4 - =", false, 0 }, // too few values |
|
3890 { "$new $eip = $new", true, 0x10000000 }, // make new variable |
|
3891 { "$new 4 +", true, 0x10000004 }, // see prior assignments |
|
3892 { ".cfa 42 = 10", false, 0 } // can't set constants |
|
3893 }; |
|
3894 const int evaluate_for_value_tests_2_size |
|
3895 = (sizeof (evaluate_for_value_tests_2) |
|
3896 / sizeof (evaluate_for_value_tests_2[0])); |
|
3897 - map<string, unsigned int> validate_data_2; |
|
3898 - validate_data_2["$eip"] = 0x10000000; |
|
3899 - validate_data_2["$ebp"] = 0xbfff000c; |
|
3900 - validate_data_2["$esp"] = 0xbfff0000; |
|
3901 - validate_data_2["$new"] = 0x10000000; |
|
3902 - validate_data_2[".cbSavedRegs"] = 4; |
|
3903 - validate_data_2[".cbParams"] = 4; |
|
3904 - validate_data_2[".raSearchStart"] = 0xbfff0020; |
|
3905 + map<const UniqueString*, unsigned int> validate_data_2; |
|
3906 + validate_data_2[ustr__ZSeip()] = 0x10000000; |
|
3907 + validate_data_2[ustr__ZSebp()] = 0xbfff000c; |
|
3908 + validate_data_2[ustr__ZSesp()] = 0xbfff0000; |
|
3909 + validate_data_2[ToUniqueString("$new")] = 0x10000000; |
|
3910 + validate_data_2[ustr__ZDcbSavedRegs()] = 4; |
|
3911 + validate_data_2[ustr__ZDcbParams()] = 4; |
|
3912 + validate_data_2[ustr__ZDraSearchStart()] = 0xbfff0020; |
|
3913 |
|
3914 postfix_evaluator.set_dictionary(&dictionary_2); |
|
3915 for (int i = 0; i < evaluate_for_value_tests_2_size; i++) { |
|
3916 const EvaluateForValueTest *test = &evaluate_for_value_tests_2[i]; |
|
3917 unsigned int result; |
|
3918 if (postfix_evaluator.EvaluateForValue(test->expression, &result) |
|
3919 != test->evaluable) { |
|
3920 fprintf(stderr, "FAIL: evaluate for value test %d, " |
|
3921 @@ -353,40 +370,43 @@ |
|
3922 if (test->evaluable && result != test->value) { |
|
3923 fprintf(stderr, "FAIL: evaluate for value test %d, " |
|
3924 "expected value to be 0x%x, but it was 0x%x\n", |
|
3925 i, test->value, result); |
|
3926 return false; |
|
3927 } |
|
3928 } |
|
3929 |
|
3930 - for (map<string, unsigned int>::iterator v = validate_data_2.begin(); |
|
3931 + for (map<const UniqueString*, unsigned int>::iterator v = |
|
3932 + validate_data_2.begin(); |
|
3933 v != validate_data_2.end(); v++) { |
|
3934 - map<string, unsigned int>::iterator a = dictionary_2.find(v->first); |
|
3935 + map<const UniqueString*, unsigned int>::iterator a = |
|
3936 + dictionary_2.find(v->first); |
|
3937 if (a == dictionary_2.end()) { |
|
3938 fprintf(stderr, "FAIL: evaluate for value dictionary check: " |
|
3939 "expected dict[\"%s\"] to be 0x%x, but it was unset\n", |
|
3940 - v->first.c_str(), v->second); |
|
3941 + FromUniqueString(v->first), v->second); |
|
3942 return false; |
|
3943 } else if (a->second != v->second) { |
|
3944 fprintf(stderr, "FAIL: evaluate for value dictionary check: " |
|
3945 "expected dict[\"%s\"] to be 0x%x, but it was 0x%x\n", |
|
3946 - v->first.c_str(), v->second, a->second); |
|
3947 + FromUniqueString(v->first), v->second, a->second); |
|
3948 return false; |
|
3949 } |
|
3950 dictionary_2.erase(a); |
|
3951 } |
|
3952 |
|
3953 - map<string, unsigned int>::iterator remaining = dictionary_2.begin(); |
|
3954 + map<const UniqueString*, unsigned int>::iterator remaining = |
|
3955 + dictionary_2.begin(); |
|
3956 if (remaining != dictionary_2.end()) { |
|
3957 fprintf(stderr, "FAIL: evaluation of test expressions put unexpected " |
|
3958 "values in dictionary:\n"); |
|
3959 for (; remaining != dictionary_2.end(); remaining++) |
|
3960 fprintf(stderr, " dict[\"%s\"] == 0x%x\n", |
|
3961 - remaining->first.c_str(), remaining->second); |
|
3962 + FromUniqueString(remaining->first), remaining->second); |
|
3963 return false; |
|
3964 } |
|
3965 |
|
3966 return true; |
|
3967 } |
|
3968 |
|
3969 |
|
3970 } // namespace |
|
3971 diff --git a/src/processor/stackwalker_amd64.cc b/src/processor/stackwalker_amd64.cc |
|
3972 --- a/src/processor/stackwalker_amd64.cc |
|
3973 +++ b/src/processor/stackwalker_amd64.cc |
|
3974 @@ -50,49 +50,49 @@ |
|
3975 |
|
3976 const StackwalkerAMD64::CFIWalker::RegisterSet |
|
3977 StackwalkerAMD64::cfi_register_map_[] = { |
|
3978 // It may seem like $rip and $rsp are callee-saves, because the callee is |
|
3979 // responsible for having them restored upon return. But the callee_saves |
|
3980 // flags here really means that the walker should assume they're |
|
3981 // unchanged if the CFI doesn't mention them --- clearly wrong for $rip |
|
3982 // and $rsp. |
|
3983 - { "$rax", NULL, false, |
|
3984 + { ToUniqueString("$rax"), NULL, false, |
|
3985 StackFrameAMD64::CONTEXT_VALID_RAX, &MDRawContextAMD64::rax }, |
|
3986 - { "$rdx", NULL, false, |
|
3987 + { ToUniqueString("$rdx"), NULL, false, |
|
3988 StackFrameAMD64::CONTEXT_VALID_RDX, &MDRawContextAMD64::rdx }, |
|
3989 - { "$rcx", NULL, false, |
|
3990 + { ToUniqueString("$rcx"), NULL, false, |
|
3991 StackFrameAMD64::CONTEXT_VALID_RCX, &MDRawContextAMD64::rcx }, |
|
3992 - { "$rbx", NULL, true, |
|
3993 + { ToUniqueString("$rbx"), NULL, true, |
|
3994 StackFrameAMD64::CONTEXT_VALID_RBX, &MDRawContextAMD64::rbx }, |
|
3995 - { "$rsi", NULL, false, |
|
3996 + { ToUniqueString("$rsi"), NULL, false, |
|
3997 StackFrameAMD64::CONTEXT_VALID_RSI, &MDRawContextAMD64::rsi }, |
|
3998 - { "$rdi", NULL, false, |
|
3999 + { ToUniqueString("$rdi"), NULL, false, |
|
4000 StackFrameAMD64::CONTEXT_VALID_RDI, &MDRawContextAMD64::rdi }, |
|
4001 - { "$rbp", NULL, true, |
|
4002 + { ToUniqueString("$rbp"), NULL, true, |
|
4003 StackFrameAMD64::CONTEXT_VALID_RBP, &MDRawContextAMD64::rbp }, |
|
4004 - { "$rsp", ".cfa", false, |
|
4005 + { ToUniqueString("$rsp"), ToUniqueString(".cfa"), false, |
|
4006 StackFrameAMD64::CONTEXT_VALID_RSP, &MDRawContextAMD64::rsp }, |
|
4007 - { "$r8", NULL, false, |
|
4008 + { ToUniqueString("$r8"), NULL, false, |
|
4009 StackFrameAMD64::CONTEXT_VALID_R8, &MDRawContextAMD64::r8 }, |
|
4010 - { "$r9", NULL, false, |
|
4011 + { ToUniqueString("$r9"), NULL, false, |
|
4012 StackFrameAMD64::CONTEXT_VALID_R9, &MDRawContextAMD64::r9 }, |
|
4013 - { "$r10", NULL, false, |
|
4014 + { ToUniqueString("$r10"), NULL, false, |
|
4015 StackFrameAMD64::CONTEXT_VALID_R10, &MDRawContextAMD64::r10 }, |
|
4016 - { "$r11", NULL, false, |
|
4017 + { ToUniqueString("$r11"), NULL, false, |
|
4018 StackFrameAMD64::CONTEXT_VALID_R11, &MDRawContextAMD64::r11 }, |
|
4019 - { "$r12", NULL, true, |
|
4020 + { ToUniqueString("$r12"), NULL, true, |
|
4021 StackFrameAMD64::CONTEXT_VALID_R12, &MDRawContextAMD64::r12 }, |
|
4022 - { "$r13", NULL, true, |
|
4023 + { ToUniqueString("$r13"), NULL, true, |
|
4024 StackFrameAMD64::CONTEXT_VALID_R13, &MDRawContextAMD64::r13 }, |
|
4025 - { "$r14", NULL, true, |
|
4026 + { ToUniqueString("$r14"), NULL, true, |
|
4027 StackFrameAMD64::CONTEXT_VALID_R14, &MDRawContextAMD64::r14 }, |
|
4028 - { "$r15", NULL, true, |
|
4029 + { ToUniqueString("$r15"), NULL, true, |
|
4030 StackFrameAMD64::CONTEXT_VALID_R15, &MDRawContextAMD64::r15 }, |
|
4031 - { "$rip", ".ra", false, |
|
4032 + { ToUniqueString("$rip"), ToUniqueString(".ra"), false, |
|
4033 StackFrameAMD64::CONTEXT_VALID_RIP, &MDRawContextAMD64::rip }, |
|
4034 }; |
|
4035 |
|
4036 StackwalkerAMD64::StackwalkerAMD64(const SystemInfo* system_info, |
|
4037 const MDRawContextAMD64* context, |
|
4038 MemoryRegion* memory, |
|
4039 const CodeModules* modules, |
|
4040 StackFrameSymbolizer* resolver_helper) |
|
4041 diff --git a/src/processor/stackwalker_arm.cc b/src/processor/stackwalker_arm.cc |
|
4042 --- a/src/processor/stackwalker_arm.cc |
|
4043 +++ b/src/processor/stackwalker_arm.cc |
|
4044 @@ -76,21 +76,30 @@ |
|
4045 return frame; |
|
4046 } |
|
4047 |
|
4048 StackFrameARM* StackwalkerARM::GetCallerByCFIFrameInfo( |
|
4049 const vector<StackFrame*> &frames, |
|
4050 CFIFrameInfo* cfi_frame_info) { |
|
4051 StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back()); |
|
4052 |
|
4053 - static const char* register_names[] = { |
|
4054 - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", |
|
4055 - "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", |
|
4056 - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", |
|
4057 - "fps", "cpsr", |
|
4058 + static const UniqueString *register_names[] = { |
|
4059 + ToUniqueString("r0"), ToUniqueString("r1"), |
|
4060 + ToUniqueString("r2"), ToUniqueString("r3"), |
|
4061 + ToUniqueString("r4"), ToUniqueString("r5"), |
|
4062 + ToUniqueString("r6"), ToUniqueString("r7"), |
|
4063 + ToUniqueString("r8"), ToUniqueString("r9"), |
|
4064 + ToUniqueString("r10"), ToUniqueString("r11"), |
|
4065 + ToUniqueString("r12"), ToUniqueString("sp"), |
|
4066 + ToUniqueString("lr"), ToUniqueString("pc"), |
|
4067 + ToUniqueString("f0"), ToUniqueString("f1"), |
|
4068 + ToUniqueString("f2"), ToUniqueString("f3"), |
|
4069 + ToUniqueString("f4"), ToUniqueString("f5"), |
|
4070 + ToUniqueString("f6"), ToUniqueString("f7"), |
|
4071 + ToUniqueString("fps"), ToUniqueString("cpsr"), |
|
4072 NULL |
|
4073 }; |
|
4074 |
|
4075 // Populate a dictionary with the valid register values in last_frame. |
|
4076 CFIFrameInfo::RegisterValueMap<uint32_t> callee_registers; |
|
4077 for (int i = 0; register_names[i]; i++) |
|
4078 if (last_frame->context_validity & StackFrameARM::RegisterValidFlag(i)) |
|
4079 callee_registers[register_names[i]] = last_frame->context.iregs[i]; |
|
4080 @@ -119,17 +128,17 @@ |
|
4081 // Call Standard for the ARM Architecture, which the Linux ABI follows. |
|
4082 frame->context_validity |= StackFrameARM::RegisterValidFlag(i); |
|
4083 frame->context.iregs[i] = last_frame->context.iregs[i]; |
|
4084 } |
|
4085 } |
|
4086 // If the CFI doesn't recover the PC explicitly, then use .ra. |
|
4087 if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_PC)) { |
|
4088 CFIFrameInfo::RegisterValueMap<uint32_t>::iterator entry = |
|
4089 - caller_registers.find(".ra"); |
|
4090 + caller_registers.find(ustr__ZDra()); |
|
4091 if (entry != caller_registers.end()) { |
|
4092 if (fp_register_ == -1) { |
|
4093 frame->context_validity |= StackFrameARM::CONTEXT_VALID_PC; |
|
4094 frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = entry->second; |
|
4095 } else { |
|
4096 // The CFI updated the link register and not the program counter. |
|
4097 // Handle getting the program counter from the link register. |
|
4098 frame->context_validity |= StackFrameARM::CONTEXT_VALID_PC; |
|
4099 @@ -138,17 +147,17 @@ |
|
4100 frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = |
|
4101 last_frame->context.iregs[MD_CONTEXT_ARM_REG_LR]; |
|
4102 } |
|
4103 } |
|
4104 } |
|
4105 // If the CFI doesn't recover the SP explicitly, then use .cfa. |
|
4106 if (!(frame->context_validity & StackFrameARM::CONTEXT_VALID_SP)) { |
|
4107 CFIFrameInfo::RegisterValueMap<uint32_t>::iterator entry = |
|
4108 - caller_registers.find(".cfa"); |
|
4109 + caller_registers.find(ustr__ZDcfa()); |
|
4110 if (entry != caller_registers.end()) { |
|
4111 frame->context_validity |= StackFrameARM::CONTEXT_VALID_SP; |
|
4112 frame->context.iregs[MD_CONTEXT_ARM_REG_SP] = entry->second; |
|
4113 } |
|
4114 } |
|
4115 |
|
4116 // If we didn't recover the PC and the SP, then the frame isn't very useful. |
|
4117 static const int essentials = (StackFrameARM::CONTEXT_VALID_SP |
|
4118 diff --git a/src/processor/stackwalker_x86.cc b/src/processor/stackwalker_x86.cc |
|
4119 --- a/src/processor/stackwalker_x86.cc |
|
4120 +++ b/src/processor/stackwalker_x86.cc |
|
4121 @@ -53,33 +53,33 @@ |
|
4122 |
|
4123 const StackwalkerX86::CFIWalker::RegisterSet |
|
4124 StackwalkerX86::cfi_register_map_[] = { |
|
4125 // It may seem like $eip and $esp are callee-saves, because (with Unix or |
|
4126 // cdecl calling conventions) the callee is responsible for having them |
|
4127 // restored upon return. But the callee_saves flags here really means |
|
4128 // that the walker should assume they're unchanged if the CFI doesn't |
|
4129 // mention them, which is clearly wrong for $eip and $esp. |
|
4130 - { "$eip", ".ra", false, |
|
4131 + { ToUniqueString("$eip"), ToUniqueString(".ra"), false, |
|
4132 StackFrameX86::CONTEXT_VALID_EIP, &MDRawContextX86::eip }, |
|
4133 - { "$esp", ".cfa", false, |
|
4134 + { ToUniqueString("$esp"), ToUniqueString(".cfa"), false, |
|
4135 StackFrameX86::CONTEXT_VALID_ESP, &MDRawContextX86::esp }, |
|
4136 - { "$ebp", NULL, true, |
|
4137 + { ToUniqueString("$ebp"), NULL, true, |
|
4138 StackFrameX86::CONTEXT_VALID_EBP, &MDRawContextX86::ebp }, |
|
4139 - { "$eax", NULL, false, |
|
4140 + { ToUniqueString("$eax"), NULL, false, |
|
4141 StackFrameX86::CONTEXT_VALID_EAX, &MDRawContextX86::eax }, |
|
4142 - { "$ebx", NULL, true, |
|
4143 + { ToUniqueString("$ebx"), NULL, true, |
|
4144 StackFrameX86::CONTEXT_VALID_EBX, &MDRawContextX86::ebx }, |
|
4145 - { "$ecx", NULL, false, |
|
4146 + { ToUniqueString("$ecx"), NULL, false, |
|
4147 StackFrameX86::CONTEXT_VALID_ECX, &MDRawContextX86::ecx }, |
|
4148 - { "$edx", NULL, false, |
|
4149 + { ToUniqueString("$edx"), NULL, false, |
|
4150 StackFrameX86::CONTEXT_VALID_EDX, &MDRawContextX86::edx }, |
|
4151 - { "$esi", NULL, true, |
|
4152 + { ToUniqueString("$esi"), NULL, true, |
|
4153 StackFrameX86::CONTEXT_VALID_ESI, &MDRawContextX86::esi }, |
|
4154 - { "$edi", NULL, true, |
|
4155 + { ToUniqueString("$edi"), NULL, true, |
|
4156 StackFrameX86::CONTEXT_VALID_EDI, &MDRawContextX86::edi }, |
|
4157 }; |
|
4158 |
|
4159 StackwalkerX86::StackwalkerX86(const SystemInfo* system_info, |
|
4160 const MDRawContextX86* context, |
|
4161 MemoryRegion* memory, |
|
4162 const CodeModules* modules, |
|
4163 StackFrameSymbolizer* resolver_helper) |
|
4164 @@ -194,26 +194,26 @@ |
|
4165 } |
|
4166 } |
|
4167 |
|
4168 // Set up the dictionary for the PostfixEvaluator. %ebp and %esp are used |
|
4169 // in each program string, and their previous values are known, so set them |
|
4170 // here. |
|
4171 PostfixEvaluator<uint32_t>::DictionaryType dictionary; |
|
4172 // Provide the current register values. |
|
4173 - dictionary["$ebp"] = last_frame->context.ebp; |
|
4174 - dictionary["$esp"] = last_frame->context.esp; |
|
4175 + dictionary[ustr__ZSebp()] = last_frame->context.ebp; |
|
4176 + dictionary[ustr__ZSesp()] = last_frame->context.esp; |
|
4177 // Provide constants from the debug info for last_frame and its callee. |
|
4178 // .cbCalleeParams is a Breakpad extension that allows us to use the |
|
4179 // PostfixEvaluator engine when certain types of debugging information |
|
4180 // are present without having to write the constants into the program |
|
4181 // string as literals. |
|
4182 - dictionary[".cbCalleeParams"] = last_frame_callee_parameter_size; |
|
4183 - dictionary[".cbSavedRegs"] = last_frame_info->saved_register_size; |
|
4184 - dictionary[".cbLocals"] = last_frame_info->local_size; |
|
4185 + dictionary[ustr__ZDcbCalleeParams()] = last_frame_callee_parameter_size; |
|
4186 + dictionary[ustr__ZDcbSavedRegs()] = last_frame_info->saved_register_size; |
|
4187 + dictionary[ustr__ZDcbLocals()] = last_frame_info->local_size; |
|
4188 |
|
4189 uint32_t raSearchStart = last_frame->context.esp + |
|
4190 last_frame_callee_parameter_size + |
|
4191 last_frame_info->local_size + |
|
4192 last_frame_info->saved_register_size; |
|
4193 |
|
4194 uint32_t raSearchStartOld = raSearchStart; |
|
4195 uint32_t found = 0; // dummy value |
|
4196 @@ -232,20 +232,20 @@ |
|
4197 // Skip one slot from the stack and do another scan in order to get the |
|
4198 // actual return address. |
|
4199 raSearchStart += 4; |
|
4200 ScanForReturnAddress(raSearchStart, &raSearchStart, &found, 3); |
|
4201 } |
|
4202 |
|
4203 // The difference between raSearch and raSearchStart is unknown, |
|
4204 // but making them the same seems to work well in practice. |
|
4205 - dictionary[".raSearchStart"] = raSearchStart; |
|
4206 - dictionary[".raSearch"] = raSearchStart; |
|
4207 + dictionary[ustr__ZDraSearchStart()] = raSearchStart; |
|
4208 + dictionary[ustr__ZDraSearch()] = raSearchStart; |
|
4209 |
|
4210 - dictionary[".cbParams"] = last_frame_info->parameter_size; |
|
4211 + dictionary[ustr__ZDcbParams()] = last_frame_info->parameter_size; |
|
4212 |
|
4213 // Decide what type of program string to use. The program string is in |
|
4214 // postfix notation and will be passed to PostfixEvaluator::Evaluate. |
|
4215 // Given the dictionary and the program string, it is possible to compute |
|
4216 // the return address and the values of other registers in the calling |
|
4217 // function. Because of bugs described below, the stack may need to be |
|
4218 // scanned for these values. The results of program string evaluation |
|
4219 // will be used to determine whether to scan for better values. |
|
4220 @@ -325,18 +325,18 @@ |
|
4221 } |
|
4222 |
|
4223 // Now crank it out, making sure that the program string set at least the |
|
4224 // two required variables. |
|
4225 PostfixEvaluator<uint32_t> evaluator = |
|
4226 PostfixEvaluator<uint32_t>(&dictionary, memory_); |
|
4227 PostfixEvaluator<uint32_t>::DictionaryValidityType dictionary_validity; |
|
4228 if (!evaluator.Evaluate(program_string, &dictionary_validity) || |
|
4229 - dictionary_validity.find("$eip") == dictionary_validity.end() || |
|
4230 - dictionary_validity.find("$esp") == dictionary_validity.end()) { |
|
4231 + dictionary_validity.find(ustr__ZSeip()) == dictionary_validity.end() || |
|
4232 + dictionary_validity.find(ustr__ZSesp()) == dictionary_validity.end()) { |
|
4233 // Program string evaluation failed. It may be that %eip is not somewhere |
|
4234 // with stack frame info, and %ebp is pointing to non-stack memory, so |
|
4235 // our evaluation couldn't succeed. We'll scan the stack for a return |
|
4236 // address. This can happen if the stack is in a module for which |
|
4237 // we don't have symbols, and that module is compiled without a |
|
4238 // frame pointer. |
|
4239 uint32_t location_start = last_frame->context.esp; |
|
4240 uint32_t location, eip; |
|
4241 @@ -344,69 +344,69 @@ |
|
4242 // if we can't find an instruction pointer even with stack scanning, |
|
4243 // give up. |
|
4244 return NULL; |
|
4245 } |
|
4246 |
|
4247 // This seems like a reasonable return address. Since program string |
|
4248 // evaluation failed, use it and set %esp to the location above the |
|
4249 // one where the return address was found. |
|
4250 - dictionary["$eip"] = eip; |
|
4251 - dictionary["$esp"] = location + 4; |
|
4252 + dictionary[ustr__ZSeip()] = eip; |
|
4253 + dictionary[ustr__ZSesp()] = location + 4; |
|
4254 trust = StackFrame::FRAME_TRUST_SCAN; |
|
4255 } |
|
4256 |
|
4257 // Since this stack frame did not use %ebp in a traditional way, |
|
4258 // locating the return address isn't entirely deterministic. In that |
|
4259 // case, the stack can be scanned to locate the return address. |
|
4260 // |
|
4261 // However, if program string evaluation resulted in both %eip and |
|
4262 // %ebp values of 0, trust that the end of the stack has been |
|
4263 // reached and don't scan for anything else. |
|
4264 - if (dictionary["$eip"] != 0 || dictionary["$ebp"] != 0) { |
|
4265 + if (dictionary[ustr__ZSeip()] != 0 || dictionary[ustr__ZSebp()] != 0) { |
|
4266 int offset = 0; |
|
4267 |
|
4268 // This scan can only be done if a CodeModules object is available, to |
|
4269 // check that candidate return addresses are in fact inside a module. |
|
4270 // |
|
4271 // TODO(mmentovai): This ignores dynamically-generated code. One possible |
|
4272 // solution is to check the minidump's memory map to see if the candidate |
|
4273 // %eip value comes from a mapped executable page, although this would |
|
4274 // require dumps that contain MINIDUMP_MEMORY_INFO, which the Breakpad |
|
4275 // client doesn't currently write (it would need to call MiniDumpWriteDump |
|
4276 // with the MiniDumpWithFullMemoryInfo type bit set). Even given this |
|
4277 // ability, older OSes (pre-XP SP2) and CPUs (pre-P4) don't enforce |
|
4278 // an independent execute privilege on memory pages. |
|
4279 |
|
4280 - uint32_t eip = dictionary["$eip"]; |
|
4281 + uint32_t eip = dictionary[ustr__ZSeip()]; |
|
4282 if (modules_ && !modules_->GetModuleForAddress(eip)) { |
|
4283 // The instruction pointer at .raSearchStart was invalid, so start |
|
4284 // looking one 32-bit word above that location. |
|
4285 - uint32_t location_start = dictionary[".raSearchStart"] + 4; |
|
4286 + uint32_t location_start = dictionary[ustr__ZDraSearchStart()] + 4; |
|
4287 uint32_t location; |
|
4288 if (ScanForReturnAddress(location_start, &location, &eip)) { |
|
4289 // This is a better return address that what program string |
|
4290 // evaluation found. Use it, and set %esp to the location above the |
|
4291 // one where the return address was found. |
|
4292 - dictionary["$eip"] = eip; |
|
4293 - dictionary["$esp"] = location + 4; |
|
4294 + dictionary[ustr__ZSeip()] = eip; |
|
4295 + dictionary[ustr__ZSesp()] = location + 4; |
|
4296 offset = location - location_start; |
|
4297 trust = StackFrame::FRAME_TRUST_CFI_SCAN; |
|
4298 } |
|
4299 } |
|
4300 |
|
4301 if (recover_ebp) { |
|
4302 // When trying to recover the previous value of the frame pointer (%ebp), |
|
4303 // start looking at the lowest possible address in the saved-register |
|
4304 // area, and look at the entire saved register area, increased by the |
|
4305 // size of |offset| to account for additional data that may be on the |
|
4306 // stack. The scan is performed from the highest possible address to |
|
4307 // the lowest, because the expectation is that the function's prolog |
|
4308 // would have saved %ebp early. |
|
4309 - uint32_t ebp = dictionary["$ebp"]; |
|
4310 + uint32_t ebp = dictionary[ustr__ZSebp()]; |
|
4311 |
|
4312 // When a scan for return address is used, it is possible to skip one or |
|
4313 // more frames (when return address is not in a known module). One |
|
4314 // indication for skipped frames is when the value of %ebp is lower than |
|
4315 // the location of the return address on the stack |
|
4316 bool has_skipped_frames = |
|
4317 (trust != StackFrame::FRAME_TRUST_CFI && ebp <= raSearchStart + offset); |
|
4318 |
|
4319 @@ -420,49 +420,49 @@ |
|
4320 location >= location_end; |
|
4321 location -= 4) { |
|
4322 if (!memory_->GetMemoryAtAddress(location, &ebp)) |
|
4323 break; |
|
4324 |
|
4325 if (memory_->GetMemoryAtAddress(ebp, &value)) { |
|
4326 // The candidate value is a pointer to the same memory region |
|
4327 // (the stack). Prefer it as a recovered %ebp result. |
|
4328 - dictionary["$ebp"] = ebp; |
|
4329 + dictionary[ustr__ZSebp()] = ebp; |
|
4330 break; |
|
4331 } |
|
4332 } |
|
4333 } |
|
4334 } |
|
4335 } |
|
4336 |
|
4337 // Create a new stack frame (ownership will be transferred to the caller) |
|
4338 // and fill it in. |
|
4339 StackFrameX86* frame = new StackFrameX86(); |
|
4340 |
|
4341 frame->trust = trust; |
|
4342 frame->context = last_frame->context; |
|
4343 - frame->context.eip = dictionary["$eip"]; |
|
4344 - frame->context.esp = dictionary["$esp"]; |
|
4345 - frame->context.ebp = dictionary["$ebp"]; |
|
4346 + frame->context.eip = dictionary[ustr__ZSeip()]; |
|
4347 + frame->context.esp = dictionary[ustr__ZSesp()]; |
|
4348 + frame->context.ebp = dictionary[ustr__ZSebp()]; |
|
4349 frame->context_validity = StackFrameX86::CONTEXT_VALID_EIP | |
|
4350 StackFrameX86::CONTEXT_VALID_ESP | |
|
4351 StackFrameX86::CONTEXT_VALID_EBP; |
|
4352 |
|
4353 // These are nonvolatile (callee-save) registers, and the program string |
|
4354 // may have filled them in. |
|
4355 - if (dictionary_validity.find("$ebx") != dictionary_validity.end()) { |
|
4356 - frame->context.ebx = dictionary["$ebx"]; |
|
4357 + if (dictionary_validity.find(ustr__ZSebx()) != dictionary_validity.end()) { |
|
4358 + frame->context.ebx = dictionary[ustr__ZSebx()]; |
|
4359 frame->context_validity |= StackFrameX86::CONTEXT_VALID_EBX; |
|
4360 } |
|
4361 - if (dictionary_validity.find("$esi") != dictionary_validity.end()) { |
|
4362 - frame->context.esi = dictionary["$esi"]; |
|
4363 + if (dictionary_validity.find(ustr__ZSesi()) != dictionary_validity.end()) { |
|
4364 + frame->context.esi = dictionary[ustr__ZSesi()]; |
|
4365 frame->context_validity |= StackFrameX86::CONTEXT_VALID_ESI; |
|
4366 } |
|
4367 - if (dictionary_validity.find("$edi") != dictionary_validity.end()) { |
|
4368 - frame->context.edi = dictionary["$edi"]; |
|
4369 + if (dictionary_validity.find(ustr__ZSedi()) != dictionary_validity.end()) { |
|
4370 + frame->context.edi = dictionary[ustr__ZSedi()]; |
|
4371 frame->context_validity |= StackFrameX86::CONTEXT_VALID_EDI; |
|
4372 } |
|
4373 |
|
4374 return frame; |
|
4375 } |
|
4376 |
|
4377 StackFrameX86* StackwalkerX86::GetCallerByCFIFrameInfo( |
|
4378 const vector<StackFrame*> &frames, |
|
4379 diff --git a/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj b/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj |
|
4380 --- a/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj |
|
4381 +++ b/src/tools/mac/dump_syms/dump_syms.xcodeproj/project.pbxproj |
|
4382 @@ -98,16 +98,22 @@ |
|
4383 B8C5B51B1166534700D34F4E /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650430B52F6D800611104 /* macho_id.cc */; }; |
|
4384 B8C5B51C1166534700D34F4E /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9BE650450B52F6D800611104 /* macho_walker.cc */; }; |
|
4385 B8C5B51D1166534700D34F4E /* dump_syms.mm in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* dump_syms.mm */; }; |
|
4386 B8C5B51E1166534700D34F4E /* dump_syms_tool.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDF186E0B1BB43700F8391B /* dump_syms_tool.mm */; }; |
|
4387 B8C5B523116653BA00D34F4E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; |
|
4388 D21F97D711CBA12300239E38 /* test_assembler_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FB0D9116CEC0600407530 /* test_assembler_unittest.cc */; }; |
|
4389 D21F97D811CBA13D00239E38 /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; }; |
|
4390 D21F97E911CBA1FF00239E38 /* test_assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE0911665B5700407530 /* test_assembler.cc */; }; |
|
4391 + D24997CC16B6C16800E588C5 /* unique_string.cc in Sources */ = {isa = PBXBuildFile; fileRef = D24997CA16B6C16800E588C5 /* unique_string.cc */; }; |
|
4392 + D24997CD16B6C16800E588C5 /* unique_string.cc in Sources */ = {isa = PBXBuildFile; fileRef = D24997CA16B6C16800E588C5 /* unique_string.cc */; }; |
|
4393 + D24997CE16B6C16800E588C5 /* unique_string.cc in Sources */ = {isa = PBXBuildFile; fileRef = D24997CA16B6C16800E588C5 /* unique_string.cc */; }; |
|
4394 + D2499A0016B9BA6A00E588C5 /* unique_string.cc in Sources */ = {isa = PBXBuildFile; fileRef = D24997CA16B6C16800E588C5 /* unique_string.cc */; }; |
|
4395 + D2499A0216B9BA9600E588C5 /* unique_string.cc in Sources */ = {isa = PBXBuildFile; fileRef = D24997CA16B6C16800E588C5 /* unique_string.cc */; }; |
|
4396 + D2499A0316B9BA9D00E588C5 /* unique_string.cc in Sources */ = {isa = PBXBuildFile; fileRef = D24997CA16B6C16800E588C5 /* unique_string.cc */; }; |
|
4397 /* End PBXBuildFile section */ |
|
4398 |
|
4399 /* Begin PBXContainerItemProxy section */ |
|
4400 8B31051411F100CF00FCF3E4 /* PBXContainerItemProxy */ = { |
|
4401 isa = PBXContainerItemProxy; |
|
4402 containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; |
|
4403 proxyType = 1; |
|
4404 remoteGlobalIDString = D21F97D111CBA0F200239E38; |
|
4405 @@ -338,16 +344,18 @@ |
|
4406 B89E0E741166575200DD08C9 /* macho_dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = macho_dump; sourceTree = BUILT_PRODUCTS_DIR; }; |
|
4407 B89E0E9511665A6400DD08C9 /* macho_reader_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = macho_reader_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; |
|
4408 B89E0E9F11665AC300DD08C9 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gtest_main.cc; path = ../../../testing/gtest/src/gtest_main.cc; sourceTree = SOURCE_ROOT; }; |
|
4409 B89E0EA011665AC300DD08C9 /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gtest-all.cc"; path = "../../../testing/gtest/src/gtest-all.cc"; sourceTree = SOURCE_ROOT; }; |
|
4410 B89E0EA311665AEA00DD08C9 /* gmock-all.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gmock-all.cc"; path = "../../../testing/src/gmock-all.cc"; sourceTree = SOURCE_ROOT; }; |
|
4411 B8C5B5111166531A00D34F4E /* dump_syms */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dump_syms; sourceTree = BUILT_PRODUCTS_DIR; }; |
|
4412 B8E8CA0C1156C854009E61B2 /* byteswap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = byteswap.h; path = ../../../common/mac/byteswap.h; sourceTree = SOURCE_ROOT; }; |
|
4413 D21F97D211CBA0F200239E38 /* test_assembler_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = test_assembler_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; |
|
4414 + D24997CA16B6C16800E588C5 /* unique_string.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = unique_string.cc; path = ../../../common/unique_string.cc; sourceTree = "<group>"; }; |
|
4415 + D24997CB16B6C16800E588C5 /* unique_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = unique_string.h; path = ../../../common/unique_string.h; sourceTree = "<group>"; }; |
|
4416 F95B422B0E0E22D100DBDE83 /* bytereader-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "bytereader-inl.h"; path = "../../../common/dwarf/bytereader-inl.h"; sourceTree = SOURCE_ROOT; }; |
|
4417 F95B422C0E0E22D100DBDE83 /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; }; |
|
4418 F95B422D0E0E22D100DBDE83 /* bytereader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bytereader.h; path = ../../../common/dwarf/bytereader.h; sourceTree = SOURCE_ROOT; }; |
|
4419 F95B422E0E0E22D100DBDE83 /* dwarf2enums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2enums.h; path = ../../../common/dwarf/dwarf2enums.h; sourceTree = SOURCE_ROOT; }; |
|
4420 F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; }; |
|
4421 F95B42300E0E22D100DBDE83 /* dwarf2reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2reader.h; path = ../../../common/dwarf/dwarf2reader.h; sourceTree = SOURCE_ROOT; }; |
|
4422 F95B42310E0E22D100DBDE83 /* line_state_machine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = line_state_machine.h; path = ../../../common/dwarf/line_state_machine.h; sourceTree = SOURCE_ROOT; }; |
|
4423 /* End PBXFileReference section */ |
|
4424 @@ -531,16 +539,18 @@ |
|
4425 D21F97D211CBA0F200239E38 /* test_assembler_unittest */, |
|
4426 ); |
|
4427 name = Products; |
|
4428 sourceTree = "<group>"; |
|
4429 }; |
|
4430 B88FAE1C11665FFD00407530 /* MODULE */ = { |
|
4431 isa = PBXGroup; |
|
4432 children = ( |
|
4433 + D24997CA16B6C16800E588C5 /* unique_string.cc */, |
|
4434 + D24997CB16B6C16800E588C5 /* unique_string.h */, |
|
4435 B88FAE1E1166603300407530 /* dwarf_cu_to_module.cc */, |
|
4436 B88FAE1F1166603300407530 /* dwarf_cu_to_module.h */, |
|
4437 B88FB0D6116CEC0600407530 /* dwarf_cu_to_module_unittest.cc */, |
|
4438 B88FAE201166603300407530 /* dwarf_line_to_module.cc */, |
|
4439 B88FAE211166603300407530 /* dwarf_line_to_module.h */, |
|
4440 B88FB0D7116CEC0600407530 /* dwarf_line_to_module_unittest.cc */, |
|
4441 B88FAE221166603300407530 /* language.cc */, |
|
4442 B88FAE231166603300407530 /* language.h */, |
|
4443 @@ -940,16 +950,17 @@ |
|
4444 }; |
|
4445 /* End PBXShellScriptBuildPhase section */ |
|
4446 |
|
4447 /* Begin PBXSourcesBuildPhase section */ |
|
4448 B84A91F1116CF784006C210E /* Sources */ = { |
|
4449 isa = PBXSourcesBuildPhase; |
|
4450 buildActionMask = 2147483647; |
|
4451 files = ( |
|
4452 + D2499A0216B9BA9600E588C5 /* unique_string.cc in Sources */, |
|
4453 B84A91FB116CF7AF006C210E /* module.cc in Sources */, |
|
4454 B84A91FC116CF7AF006C210E /* stabs_to_module.cc in Sources */, |
|
4455 B84A91FD116CF7AF006C210E /* stabs_to_module_unittest.cc in Sources */, |
|
4456 ); |
|
4457 runOnlyForDeploymentPostprocessing = 0; |
|
4458 }; |
|
4459 B88FAF2C116A591D00407530 /* Sources */ = { |
|
4460 isa = PBXSourcesBuildPhase; |
|
4461 @@ -983,56 +994,60 @@ |
|
4462 runOnlyForDeploymentPostprocessing = 0; |
|
4463 }; |
|
4464 B88FB0B6116CEABF00407530 /* Sources */ = { |
|
4465 isa = PBXSourcesBuildPhase; |
|
4466 buildActionMask = 2147483647; |
|
4467 files = ( |
|
4468 B88FB0BD116CEAE000407530 /* module_unittest.cc in Sources */, |
|
4469 B88FB0C4116CEB4100407530 /* module.cc in Sources */, |
|
4470 + D24997CE16B6C16800E588C5 /* unique_string.cc in Sources */, |
|
4471 ); |
|
4472 runOnlyForDeploymentPostprocessing = 0; |
|
4473 }; |
|
4474 B88FB0DC116CEEA800407530 /* Sources */ = { |
|
4475 isa = PBXSourcesBuildPhase; |
|
4476 buildActionMask = 2147483647; |
|
4477 files = ( |
|
4478 B88FB0E5116CEED300407530 /* dwarf2diehandler.cc in Sources */, |
|
4479 B88FB0E6116CEED300407530 /* dwarf2diehandler_unittest.cc in Sources */, |
|
4480 ); |
|
4481 runOnlyForDeploymentPostprocessing = 0; |
|
4482 }; |
|
4483 B88FB0EF116CEF1900407530 /* Sources */ = { |
|
4484 isa = PBXSourcesBuildPhase; |
|
4485 buildActionMask = 2147483647; |
|
4486 files = ( |
|
4487 + D2499A0316B9BA9D00E588C5 /* unique_string.cc in Sources */, |
|
4488 B88FB0FA116CF00E00407530 /* dwarf_line_to_module.cc in Sources */, |
|
4489 B88FB0FE116CF02400407530 /* module.cc in Sources */, |
|
4490 B88FB0FB116CF00E00407530 /* dwarf_line_to_module_unittest.cc in Sources */, |
|
4491 ); |
|
4492 runOnlyForDeploymentPostprocessing = 0; |
|
4493 }; |
|
4494 B88FB107116CF07900407530 /* Sources */ = { |
|
4495 isa = PBXSourcesBuildPhase; |
|
4496 buildActionMask = 2147483647; |
|
4497 files = ( |
|
4498 + D2499A0016B9BA6A00E588C5 /* unique_string.cc in Sources */, |
|
4499 B88FB112116CF1F000407530 /* dwarf_cu_to_module.cc in Sources */, |
|
4500 B88FB113116CF1F000407530 /* dwarf_cu_to_module_unittest.cc in Sources */, |
|
4501 B88FB114116CF1F000407530 /* language.cc in Sources */, |
|
4502 B88FB115116CF1F000407530 /* module.cc in Sources */, |
|
4503 ); |
|
4504 runOnlyForDeploymentPostprocessing = 0; |
|
4505 }; |
|
4506 B88FB11C116CF27F00407530 /* Sources */ = { |
|
4507 isa = PBXSourcesBuildPhase; |
|
4508 buildActionMask = 2147483647; |
|
4509 files = ( |
|
4510 B88FB129116CF2DD00407530 /* module.cc in Sources */, |
|
4511 B88FB12A116CF2DD00407530 /* dwarf_cfi_to_module.cc in Sources */, |
|
4512 B88FB12B116CF2DD00407530 /* dwarf_cfi_to_module_unittest.cc in Sources */, |
|
4513 + D24997CD16B6C16800E588C5 /* unique_string.cc in Sources */, |
|
4514 ); |
|
4515 runOnlyForDeploymentPostprocessing = 0; |
|
4516 }; |
|
4517 B88FB132116CF30F00407530 /* Sources */ = { |
|
4518 isa = PBXSourcesBuildPhase; |
|
4519 buildActionMask = 2147483647; |
|
4520 files = ( |
|
4521 B88FB13D116CF38300407530 /* cfi_assembler.cc in Sources */, |
|
4522 @@ -1086,16 +1101,17 @@ |
|
4523 B88FAE261166603300407530 /* dwarf_cu_to_module.cc in Sources */, |
|
4524 B88FAE271166603300407530 /* dwarf_line_to_module.cc in Sources */, |
|
4525 B88FAE281166603300407530 /* language.cc in Sources */, |
|
4526 B88FAE291166603300407530 /* module.cc in Sources */, |
|
4527 B88FAE351166673E00407530 /* dwarf_cfi_to_module.cc in Sources */, |
|
4528 B88FAE3B11666C6F00407530 /* stabs_reader.cc in Sources */, |
|
4529 B88FAE3E11666C8900407530 /* stabs_to_module.cc in Sources */, |
|
4530 4D72CAF513DFBAC2006CABE3 /* md5.cc in Sources */, |
|
4531 + D24997CC16B6C16800E588C5 /* unique_string.cc in Sources */, |
|
4532 ); |
|
4533 runOnlyForDeploymentPostprocessing = 0; |
|
4534 }; |
|
4535 D21F97CF11CBA0F200239E38 /* Sources */ = { |
|
4536 isa = PBXSourcesBuildPhase; |
|
4537 buildActionMask = 2147483647; |
|
4538 files = ( |
|
4539 D21F97E911CBA1FF00239E38 /* test_assembler.cc in Sources */, |