Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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
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)
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)
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)
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
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
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)
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
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)
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
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
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
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)
582 @DISABLE_PROCESSOR_FALSE@src_processor_postfix_evaluator_unittest_SOURCES = \
583 @DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator_unittest.cc
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)
592 @DISABLE_PROCESSOR_FALSE@src_processor_range_map_unittest_SOURCES = \
593 @DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest.cc
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
600 @DISABLE_PROCESSOR_FALSE@src_processor_minidump_stackwalk_SOURCES = \
601 @DISABLE_PROCESSOR_FALSE@ src/processor/minidump_stackwalk.cc
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 @@
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`
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
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>
750 #include "common/dwarf_cfi_to_module.h"
752 namespace google_breakpad {
754 using std::ostringstream;
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 }
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 };
784 return MakeVector(names, sizeof(names) / sizeof(names[0]));
785 }
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 };
802 return MakeVector(names, sizeof(names) / sizeof(names[0]));
803 }
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;
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);
829 return true;
830 }
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();
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];
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 }
857 void DwarfCFIToModule::Record(Module::Address address, int reg,
858 const Module::Expr &rule) {
859 assert(entry_);
861 // Is this one of this entry's initial rules?
862 if (address == entry_->address)
863 @@ -228,28 +232,30 @@
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 }
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 }
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 }
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 @@
905 #include <set>
906 #include <string>
907 #include <vector>
909 #include "common/module.h"
910 #include "common/dwarf/dwarf2reader.h"
911 #include "common/using_std_string.h"
912 +#include "common/unique_string.h"
914 namespace google_breakpad {
916 using dwarf2reader::CallFrameInfo;
917 using google_breakpad::Module;
918 using std::set;
919 using std::vector;
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);
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);
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);
942 protected:
943 string file_, section_;
944 };
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();
955 // AMD x86_64, AMD64, Intel EM64T, or Intel 64
956 - static vector<string> X86_64();
957 + static vector<const UniqueString*> X86_64();
959 // ARM.
960 - static vector<string> ARM();
961 + static vector<const UniqueString*> ARM();
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 };
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_; }
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();
1002 private:
1003 // Return the name to use for register REG.
1004 - string RegisterName(int i);
1005 + const UniqueString* RegisterName(int i);
1007 // Record RULE for register REG at ADDRESS.
1008 void Record(Module::Address address, int reg, const Module::Expr &rule);
1010 // The module to which we should add entries.
1011 Module *module_;
1013 // Map from register numbers to register names.
1014 - const vector<string> ®ister_names_;
1015 + const vector<const UniqueString*> ®ister_names_;
1017 // The reporter to use to report problems.
1018 Reporter *reporter_;
1020 // The current entry we're constructing.
1021 Module::StackFrameEntry *entry_;
1023 // The section offset of the current frame description entry, for
1024 // use in error messages.
1025 size_t entry_offset_;
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 };
1048 } // namespace google_breakpad
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"
1059 using std::vector;
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::_;
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 };
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());
1112 EXPECT_CALL(reporter, UnnamedRegister(_, _)).Times(0);
1113 EXPECT_CALL(reporter, UndefinedNotSupported(_, _)).Times(0);
1114 EXPECT_CALL(reporter, ExpressionsNotSupported(_, _)).Times(0);
1115 }
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 };
1125 class Entry: public DwarfCFIToModuleFixture, public Test { };
1127 TEST_F(Entry, Accept) {
1128 @@ -127,183 +134,190 @@
1129 }
1130 uint64 entry_address, entry_size;
1131 unsigned return_reg;
1132 };
1134 class Rule: public RuleFixture, public Test { };
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
1309 TEST(RegisterNames, I386) {
1310 - vector<string> names = DwarfCFIToModule::RegisterNames::I386();
1311 + vector<const UniqueString*> names = DwarfCFIToModule::RegisterNames::I386();
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 }
1323 TEST(RegisterNames, ARM) {
1324 - vector<string> names = DwarfCFIToModule::RegisterNames::ARM();
1325 + vector<const UniqueString*> names = DwarfCFIToModule::RegisterNames::ARM();
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 }
1339 TEST(RegisterNames, X86_64) {
1340 - vector<string> names = DwarfCFIToModule::RegisterNames::X86_64();
1341 + vector<const UniqueString*> names = DwarfCFIToModule::RegisterNames::X86_64();
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;
1369 //
1370 // FDWrapper
1371 //
1372 // Wrapper class to make sure opened file is closed.
1373 //
1374 class FDWrapper {
1375 @@ -278,17 +279,17 @@
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 }
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 }
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 @@
1440 #include "common/module.h"
1442 #include <assert.h>
1443 #include <errno.h>
1444 #include <stdio.h>
1445 #include <string.h>
1447 +#include <algorithm>
1448 #include <iostream>
1449 #include <utility>
1451 namespace google_breakpad {
1453 using std::dec;
1454 using std::endl;
1455 using std::hex;
1456 @@ -255,36 +256,50 @@
1457 strerror(errno));
1458 return false;
1459 }
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 }
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 }
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>
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"
1527 namespace google_breakpad {
1529 using std::set;
1530 using std::vector;
1531 using std::map;
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 }
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_;
1592 friend std::ostream& operator<<(std::ostream& stream, const Expr& expr);
1593 };
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;
1602 // A map from addresses to RuleMaps, representing changes that take
1603 // effect at given addresses.
1604 typedef map<Address, RuleMap> RuleChangeMap;
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>
1616 #include "breakpad_googletest_includes.h"
1617 #include "common/module.h"
1618 #include "common/using_std_string.h"
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;
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);
1634 m.AddFunction(function);
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);
1658 // Set the load address. Doing this after adding all the data to
1659 // the module must work fine.
1660 m.SetLoadAddress(0x2ab698b0b6407073LL);
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 }
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);
1688 m.AddFunction(function);
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);
1708 // Set the load address. Doing this after adding all the data to
1709 // the module must work fine.
1710 m.SetLoadAddress(0x2ab698b0b6407073LL);
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);
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);
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);
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);
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);
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);
1848 Module::StackFrameEntry* s = m.FindStackFrameEntryByAddress(0x1000);
1849 EXPECT_EQ(entry3, s);
1850 s = m.FindStackFrameEntryByAddress(0x18FF);
1851 EXPECT_EQ(entry3, s);
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"
2219 namespace {
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;
2239 class TestCodeModule : public CodeModule {
2240 public:
2241 TestCodeModule(string code_file) : code_file_(code_file) {}
2242 virtual ~TestCodeModule() {}
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 @@
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;
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;
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));
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));
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);
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);
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);
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);
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 @@
2388 // cfi_frame_info.cc: Implementation of CFIFrameInfo class.
2389 // See cfi_frame_info.h for details.
2391 #include "processor/cfi_frame_info.h"
2393 #include <string.h>
2395 +#include <algorithm>
2396 #include <sstream>
2398 #include "common/scoped_ptr.h"
2399 #include "processor/postfix_evaluator-inl.h"
2401 namespace google_breakpad {
2403 #ifdef _WIN32
2404 @@ -65,33 +66,33 @@
2405 V cfa;
2406 working = registers;
2407 if (!evaluator.EvaluateForValue(cfa_rule_, &cfa))
2408 return false;
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;
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 }
2430 - (*caller_registers)[".ra"] = ra;
2431 - (*caller_registers)[".cfa"] = cfa;
2432 + (*caller_registers)[ustr__ZDra()] = ra;
2433 + (*caller_registers)[ustr__ZDcfa()] = cfa;
2435 return true;
2436 }
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 }
2477 return stream.str();
2478 }
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';
2486 - name_.clear();
2487 + name_ = ustr__empty();
2488 expression_.clear();
2490 char *cursor;
2491 static const char token_breaks[] = " \t\r\n";
2492 char *token = strtok_r(working_copy.get(), token_breaks, &cursor);
2494 for (;;) {
2495 // End of rule set?
2496 if (!token) return Report();
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 }
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 }
2533 void CFIFrameInfoParseHandler::CFARule(const string &expression) {
2534 // 'expression' is a postfix expression string.
2535 frame_info_->SetCFARule(Module::Expr(expression));
2536 }
2538 void CFIFrameInfoParseHandler::RARule(const string &expression) {
2539 frame_info_->SetRARule(Module::Expr(expression));
2540 }
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 }
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 @@
2554 #ifndef PROCESSOR_CFI_FRAME_INFO_H_
2555 #define PROCESSOR_CFI_FRAME_INFO_H_
2557 #include <map>
2558 #include <string>
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"
2565 namespace google_breakpad {
2567 using std::map;
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> { };
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 }
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 @@
2599 // Serialize the rules in this object into a string in the format
2600 // of STACK CFI records.
2601 string Serialize() const;
2603 private:
2605 // A map from register names onto evaluation rules.
2606 - typedef map<string, Module::Expr> RuleMap;
2607 + typedef map<const UniqueString*, Module::Expr> RuleMap;
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_;
2616 @@ -145,17 +146,18 @@
2617 Handler() { }
2618 virtual ~Handler() { }
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;
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 };
2630 // Construct a parser which feeds its results to HANDLER.
2631 CFIRuleParser(Handler *handler) : handler_(handler) { }
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();
2641 // The handler to which the parser reports its findings.
2642 Handler *handler_;
2644 // Working data.
2645 - string name_, expression_;
2646 + const UniqueString* name_;
2647 + string expression_;
2648 };
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) { }
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);
2663 private:
2664 CFIFrameInfo *frame_info_;
2665 };
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;
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;
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;
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"
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;
2725 @@ -107,41 +112,47 @@
2726 TEST_F(Simple, SetCFAAndRARule) {
2727 ExpectNoMemoryReferences();
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()]);
2739 ASSERT_EQ(".cfa: 330903416631436410 .ra: 5870666104170902211",
2740 cfi.Serialize());
2741 }
2743 TEST_F(Simple, SetManyRules) {
2744 ExpectNoMemoryReferences();
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();
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 }
2802 class Scope: public CFIFixture, public Test { };
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 }
2810 // The current frame's registers should be in scope when evaluating
2811 // the CFA rule.
2812 TEST_F(Scope, CFASeesCurrentRegs) {
2813 ExpectNoMemoryReferences();
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 }
2831 // .cfa should be in scope in the return address expression.
2832 TEST_F(Scope, RASeesCFA) {
2833 ExpectNoMemoryReferences();
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 }
2844 // There should be no value for .ra in scope when evaluating the CFA rule.
2845 TEST_F(Scope, RALacksRA) {
2846 ExpectNoMemoryReferences();
2848 cfi.SetCFARule(Module::Expr("0"));
2849 cfi.SetRARule(Module::Expr(".ra"));
2850 @@ -221,64 +234,69 @@
2851 &caller_registers));
2852 }
2854 // The current frame's registers should be in scope in the return
2855 // address expression.
2856 TEST_F(Scope, RASeesCurrentRegs) {
2857 ExpectNoMemoryReferences();
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 }
2872 // .cfa should be in scope for register rules.
2873 TEST_F(Scope, RegistersSeeCFA) {
2874 ExpectNoMemoryReferences();
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 }
2888 // The return address should not be in scope for register rules.
2889 TEST_F(Scope, RegsLackRA) {
2890 ExpectNoMemoryReferences();
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 }
2901 // Register rules can see the current frame's register values.
2902 TEST_F(Scope, RegsSeeRegs) {
2903 ExpectNoMemoryReferences();
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 }
2926 // Each rule's temporaries are separate.
2927 TEST_F(Scope, SeparateTempsRA) {
2928 ExpectNoMemoryReferences();
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 }
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 };
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 }
2954 TEST_F(Parser, RA) {
2955 EXPECT_CALL(mock_handler, RARule("notoriety")).WillOnce(Return());
2956 EXPECT_TRUE(parser.Parse(".ra: notoriety"));
2957 }
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 }
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 }
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 }
2990 TEST_F(Parser, WhitespaceLoneColon) {
2991 EXPECT_FALSE(parser.Parse(" \n:\t "));
2992 }
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 }
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 }
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 }
3018 class ParseHandlerFixture: public CFIFixture {
3019 public:
3020 ParseHandlerFixture() : CFIFixture(), handler(&cfi) { }
3021 CFIFrameInfoParseHandler handler;
3022 };
3024 class ParseHandler: public ParseHandlerFixture, public Test { };
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 }
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 }
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 };
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 };
3099 class SimpleWalker: public SimpleCFIWalkerFixture, public Test { };
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)));
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"));
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"
3135 namespace {
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;
3159 class TestCodeModule : public CodeModule {
3160 public:
3161 explicit TestCodeModule(string code_file) : code_file_(code_file) {}
3162 virtual ~TestCodeModule() {}
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 @@
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;
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;
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));
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));
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);
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);
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);
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);
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 {
3309 using std::istringstream;
3310 using std::ostringstream;
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(); }
3323 private:
3324 - vector<string> *stack_;
3325 + vector<StackElem<ValueType> > *stack_;
3326 };
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 }
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 }
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 }
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 }
3407 // Ensure that the stack is cleared before returning.
3408 - AutoStackClearer clearer(&stack_);
3409 + AutoStackClearer<ValueType> clearer(&stack_);
3411 if (!EvaluateInternal(expr.postfix_, assigned))
3412 return false;
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_) {
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_);
3430 if (!EvaluateInternal(expr.postfix_, NULL))
3431 return false;
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 }
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;
3452 - string token = stack_.back();
3453 + StackElem<ValueType> el = stack_.back();
3454 stack_.pop_back();
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 }
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 }
3520 *value = iterator->second;
3521 }
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 }
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 }
3548 } // namespace google_breakpad
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__
3559 #include <map>
3560 #include <string>
3561 #include <vector>
3563 #include "common/using_std_string.h"
3564 +#include "common/unique_string.h"
3565 #include "common/module.h"
3567 namespace google_breakpad {
3569 using std::map;
3570 using std::vector;
3572 class MemoryRegion;
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;
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 };
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);
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);
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);
3626 // Pushes a new value onto the stack.
3627 void PushValue(const ValueType &value);
3629 @@ -166,15 +181,15 @@
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_;
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 };
3642 } // namespace google_breakpad
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"
3654 namespace {
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;
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;
3686 // The number of tests.
3687 unsigned int evaluate_test_count;
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 };
3696 struct EvaluateForValueTest {
3697 // Expression passed to PostfixEvaluator::Evaluate.
3698 const string expression;
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;
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;
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 };
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 }
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;
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);
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 }
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 }
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 }
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;
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 }
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 }
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 }
3966 return true;
3967 }
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 @@
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 };
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 }
4048 StackFrameARM* StackwalkerARM::GetCallerByCFIFrameInfo(
4049 const vector<StackFrame*> &frames,
4050 CFIFrameInfo* cfi_frame_info) {
4051 StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back());
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 };
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 }
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 @@
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 };
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 }
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;
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;
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 }
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;
4210 - dictionary[".cbParams"] = last_frame_info->parameter_size;
4211 + dictionary[ustr__ZDcbParams()] = last_frame_info->parameter_size;
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 }
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 }
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 }
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;
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.
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 }
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()];
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);
4319 @@ -420,49 +420,49 @@
4320 location >= location_end;
4321 location -= 4) {
4322 if (!memory_->GetMemoryAtAddress(location, &ebp))
4323 break;
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 }
4337 // Create a new stack frame (ownership will be transferred to the caller)
4338 // and fill it in.
4339 StackFrameX86* frame = new StackFrameX86();
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;
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 }
4374 return frame;
4375 }
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 */
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 */
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 */,